deleyd
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:
The non-Linq solution would be something like:
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.
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);
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]);
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.
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?
Hi,
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
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
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?)
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?)
Hi,
Your function will have access to i and j, the only thing is that the function should return a bool.
Your function will have access to i and j, the only thing is that the function should return a bool.
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);
What would be the correct syntax for that?
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.
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.
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();
Is there a way to do this in one step instead of two?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
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?
ASKER
is there a way to get the Distinct without using the dot format? \
Thank you for your help!
Thank you for your help!
Hi!
As long as Distinct is applied to the custom result, no. Please, let me know if you need more help.
As long as Distinct is applied to the custom result, no. Please, let me know if you need more help.
You can create a function like Compare or something that can be used in the where clause:
where Compare(item1, item2)