Get all pairs in a list using LINQ

前端 未结 3 1192
攒了一身酷
攒了一身酷 2020-12-09 04:02

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

相关标签:
3条回答
  • 2020-12-09 04:47

    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();
    
    0 讨论(0)
  • 2020-12-09 05:03

    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.

    0 讨论(0)
  • 2020-12-09 05:07

    You could solve it like this:

     var list = new[] { 1, 2, 3, 4 };
    
     var pairs = from l1 in list
                 from l2 in list.Except(new[] { l1 })
                 where l1 < l2
                 select new { l1, l2 };
    
     foreach (var pair in pairs)
     {
        Console.WriteLine(pair.l1 + ", " + pair.l2);
     }
    
    0 讨论(0)
提交回复
热议问题