Avatar of deleyd
deleyd
Flag for United States of America asked on

Linq to select all pairs from a list

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.
C#LINQ Query

Avatar of undefined
Last Comment
Eduard Ghergu

8/22/2022 - Mon
Eduard Ghergu

Hi,

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

 where Compare(item1, item2)
deleyd

ASKER
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 Ghergu

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
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
deleyd

ASKER
(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 Ghergu

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

ASKER
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?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Eduard Ghergu

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.
deleyd

ASKER
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?
ASKER CERTIFIED SOLUTION
Eduard Ghergu

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
deleyd

ASKER
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?
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
deleyd

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

Thank you for your help!
Eduard Ghergu

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