Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all pairs in a list using LINQ

How do I get all possible pairs of items in a list (order not relevant)?

E.g. if I have

var list = { 1, 2, 3, 4 };

I would like to get these tuples:

var pairs = {
   new Tuple(1, 2), new Tuple(1, 3), new Tuple(1, 4),
   new Tuple(2, 3), new Tuple(2, 4)
   new Tuple(3, 4)
}
like image 508
dilbert Avatar asked Aug 30 '11 10:08

dilbert


2 Answers

Slight reformulation of cgeers answer to get you the tuples you want instead of arrays:

var combinations = from item1 in list
                   from item2 in list
                   where item1 < item2
                   select Tuple.Create(item1, item2);

(Use ToList or ToArray if you want.)

In non-query-expression form (reordered somewhat):

var combinations = list.SelectMany(x => list, (x, y) => Tuple.Create(x, y))
                       .Where(tuple => tuple.Item1 < tuple.Item2);

Both of these will actually consider n2 values instead of n2/2 values, although they'll end up with the correct answer. An alternative would be:

var combinations = list.SelectMany((x, i) => list.Skip(i + 1), (x, y) => Tuple.Create(x, y));

... but this uses Skip which may also not be optimized. It probably doesn't matter, to be honest - I'd pick whichever one is most appropriate for your usage.

like image 74
Jon Skeet Avatar answered Sep 20 '22 14:09

Jon Skeet


Calculate the Cartesian product to determine all the possible combinations.

For example:

var combinations = from item in list
                   from item2 in list
                   where item < item2
                   select new[] { item, item2 };

You can find more information about calculating a cartesian product using LINQ here:

http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx

You can then convert it to a collection of Tuple objects.

var pairs = new List<Tuple<int, int>>();
foreach (var pair in combinations)
{
    var tuple = new Tuple<int, int>(pair[0], pair[1]);
    pairs.Add(tuple);
}

Or in short:

var combinations = (from item in list
                    from item2 in list
                    where item < item2
                    select new Tuple<int, int>(item, item2)).ToList();
like image 39
Christophe Geers Avatar answered Sep 20 '22 14:09

Christophe Geers