Linq to select all pairs from a list

deleyd
deleyd used Ask the Experts™
on
I'm looking for a C# LINQ statement that will return all pairs from a list.

I've seen solution of the form:
var combinations = from item1 in list
                   from item2 in list
                   where item1 < item2
                   select Tuple.Create(item1, item2);

Open in new window

My problem is the (item1 < item2). What if these are objects that can't be compared?

The non-Linq solution would be something like:
for (int I=0; I < list.Count; ++I)
    for (int j = I+1; j < list.Count; ++j)
        pairs.Add(new Pair(list[I], list[j]);

Open in new window


So if list = {a,b,c,d,e}
the pairs would be:
{a,b}
{a,c}
{a,d}
{a,e}
{b,c}
{b,d}
{b,e}
{c,d}
{c,e}
{d,e}

(An item is not paired with itself)
And we don't want both {a,e} and {e,a}. Just the first one.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,

You can create a function like Compare or something that can be used in the where clause:

 where Compare(item1, item2)
deleydSoftware Engineer

Author

Commented:
If the list is ordered, is there a way to leverage the order of the list? Some way of converting the for loops using indexes, where it's easy to compare indexes, into a Linq statement?
Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,
If the list is ordered, is there a way to leverage the order of the list?
I don’t understand the question.
In a list, the item index is just a way to get access to it.
If you want, you can use an OrderedCollection or OrderedDictionary
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

deleydSoftware Engineer

Author

Commented:
(Sorry I haven't replied sooner.)

Well in the sample code using for loops a compare function would be comparing I with j.

(Should be a lowercase i. The spelling 'corrector' kept disagreeing.)

But in a Linq statement I don't have access to I and j. (Or do I?)
Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,
Your function will have access to i and j, the only thing is that the function should return a bool.
deleydSoftware Engineer

Author

Commented:
Can I create a Linq statement something like:
var combinations = from item1 in list
                   from item2 in list
                   where j < i
                   select Tuple.Create(item1, item2);

Open in new window

What would be the correct syntax for that?
Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,
In the end, what is i and what is j?
If you’ll start with
var combinations = from item1 in list
                   from item2 in list;
You be able to add any conditions do you want and select whatever you want.
deleydSoftware Engineer

Author

Commented:
How about can I wedge in the .Distinct() qualifier so there are no duplicates?
var combinations = from item1 in list
                   from item2 in list
                   where item1 != item2
                   select Tuple.Create(item1, item2);
var pairs = conbinations.Distinct();

Open in new window

Is there a way to do this in one step instead of two?
Architect - Coder - Mentor
Commented:
Hi,
Do you mean:
var combinations = (from item1 in list
                   from item2 in list
                   where item1 != item2
                   select Tuple.Create(item1, item2))
.Distinct();

Open in new window

?
deleydSoftware Engineer

Author

Commented:
OK so I have to put parentheses around it all and then append a .Distinct()

Is Linq smart enough to do this in an efficient manner? Or does it create list.Count() squared items and then filter out the duplicates?

Actually it's looking like it's not too much of a hit if it creates all the possible combinations and then just weeds out the duplicates, so thank you this is the answer I was looking for.

Oh is there a way to get the Distinct without using the dot format?
deleydSoftware Engineer

Author

Commented:
is there a way to get the Distinct without using the dot format? \

Thank you for your help!
Eduard GherguArchitect - Coder - Mentor

Commented:
Hi!
As long as Distinct is applied to the custom result, no. Please, let me know if you need more help.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial