Combination Generator in Linq

Combination Generator in Linq

For what it's worth, try something like this:

public static IEnumerable<string> GetPermutations(string s)
{
if (s.Length > 1)
return from ch in s
from permutation in GetPermutations(s.Remove(s.IndexOf(ch), 1))
select string.Format("{0}{1}", ch, permutation);

else
return new string[] { s };
}

How to use LINQ to find all combinations of n items from a set of numbers?

Usage:

var results = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.DifferentCombinations(3);

Code:

public static class Ex
{
public static IEnumerable<IEnumerable<T>> DifferentCombinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).DifferentCombinations(k - 1).Select(c => (new[] {e}).Concat(c)));
}
}

getting repeated combinations using LINQ

LINQ is excellent for searching; it's much worse at generating, so it is a wrong tool for the job. So is recursion (although it is a better choice than LINQ). What you need is two nested loops, like this:

var elements = new [] {1, 2};
for (var i = 0 ; i != 5 ; i++) {
for (int j = 0 ; j != 5 ; j++) {
if (i == j) continue;
var data = new int[5];
data[i] = elements[0];
data[j] = elements[1];
ProcessCombination(data);
}
}

Here is what the code does: at each iteration of the inner loop it places the first and the second element from the elements array at distinct positions i and j. Nested loops go from 0 to 5, making sure all position combinations are covered.

Generate all Combinations from Multiple (n) Lists

Hope this helps.

class NListBuilder

{
Dictionary<int, List<string>> tags = new Dictionary<int, List<string>>();

public NListBuilder()
{
tags.Add(1, new List<string>() { "A", "B", "C" });
tags.Add(2, new List<string>() { "+", "-", "*" });
tags.Add(3, new List<string>() { "1", "2", "3" });
}

public List<string> AllCombos
{
get
{
return GetCombos(tags);
}
}

List<string> GetCombos(IEnumerable<KeyValuePair<int, List<string>>> remainingTags)
{
if (remainingTags.Count() == 1)
{
return remainingTags.First().Value;
}
else
{
var current = remainingTags.First();
List<string> outputs = new List<string>();
List<string> combos = GetCombos(remainingTags.Where(tag => tag.Key != current.Key));

foreach (var tagPart in current.Value)
{
foreach (var combo in combos)
{
outputs.Add(tagPart + combo);
}
}

return outputs;
}

}
}

Select all unique combinations of a single list, with no repeats, using LINQ

Sure - you can do it in a single call to SelectMany with an embedded call to Skip:

var query = slotIds.SelectMany((value, index) => slotIds.Skip(index + 1),
(first, second) => new { first, second });

Here's an alternative option, which doesn't use quite such an esoteric overload of SelectMany:

var query = from pair in slotIds.Select((value, index) => new { value, index })
from second in slotIds.Skip(pair.index + 1)
select new { first = pair.value, second };

These do basically the same thing, just in slightly different ways.

Here's another option which is much closer to your original:

var query = from index in Enumerable.Range(0, slotIds.Count)
let first = slotIds[index] // Or use ElementAt
from second in slotIds.Skip(index + 1)
select new { first, second };

How to select distinct based on combination of two fields with LINQ?

You can select just the name and age into an anonymous type, and then use Distinct():

var results = context.people
.Select(p => new { p.Name, p.Age })
.Distinct();

Obviously that won't give you the height, but then there is no single height. If you want all the heights as well, you need to group instead:

var results = context.people
.GroupBy(p => new { p.Name, p.Age });

That will give you a sequence of groupings, where each grouping contains all the people with the same name and age.

Combination Generator

Do you like 1 letter variable names...? :D I don't even know how it works now. It uses bit masks to find every combination of subarrays of length n; then it uses some mod math to find every combination of 1 from each subarray; then it spits out that number. Sort order isn't ideal.

public class Perms {
private static String[][] array = new String[][] {
{ "1", "2", "3" },
{ "4", "5", "6" },
{ "7", "8", "9" },
{ "10", "11", "12" }
};
private static int combinationLength = 2;
public static void main(String[] args) {
// Get combinations of subarrays
for (int i = 0; i < Math.pow(2, array.length); ++i) {
int c = 0;
for (int j = 1; j <= Math.pow(2, array.length); j <<= 1)
if ((i & j) != 0)
++c;
if (c == combinationLength) {
String[][] maskedArray = new String[combinationLength][];
for (int l = 1, j = 0, k = 0; l <= Math.pow(2, array.length); l <<= 1, ++j)
if ((i & l) != 0) {
maskedArray[k] = array[j];
++k;
}
// Get combinations of one element per subarray
int l = 1;
for (int j = 0; j < maskedArray.length; ++j)
l *= maskedArray[j].length;
for (int j = 0; j < l; ++j) {
String s = "";
int m = j;
for (int k = maskedArray.length-1; k >= 0; --k) {
s = maskedArray[k][m % maskedArray[k].length] + "," + s;
m /= maskedArray[k].length;
}
// Spit out a result
System.out.println(s.substring(0, s.length()-1));
}
}
}
}
}


Related Topics



Leave a reply



Submit