Sungguk Lim
Sungguk Lim

Reputation: 6228

check existense between two IEnumerable

IEnumerable<String> existedThings = 
        from mdinfo in mdInfoTotal select mdinfo.ItemNo;

IEnumerable<String> thingsToSave = 
        from item in lbXReadSuccess.Items.Cast<ListItem>() select item.Value;

Here are two IEnumerable.

I want to check whether a value in existedThings exist in thingsToSave.

O.K. I can do that with 3 line code.

bool hasItemNo;
foreach(string itemNo in existedThings)
    hasItemNo= thingsToSave.Contains(itemNo);

But, It looks dirty.

I just want to know if there is better solution.

Upvotes: 6

Views: 1188

Answers (7)

VMAtm
VMAtm

Reputation: 28355

 int[] id1 = { 44, 26, 92, 30, 71, 38 };
 int[] id2 = { 39, 59, 83, 47, 26, 4, 30 };

 IEnumerable<int> both = id1.Intersect(id2);

 foreach (int id in both)
     Console.WriteLine(id);

 //Console.WriteLine((both.Count() > 0).ToString());
 Console.WriteLine(both.Any().ToString());

Look for the Enumerable.Intersect Method

Upvotes: 9

Hans Passant
Hans Passant

Reputation: 941465

The upvoted answers propose an algorithm that will have O(n^2) complexity if the IEnumerable wasn't derived from a class that implements ICollection<>. A Linq query for example. The Count() extension method then has to iterate all elements to count them. That's not cool. You only need to check if the result contains any elements:

 bool hasItemNo = existedThings.Intersect(thingsToSave).Any();

The order matters btw, make the enumeration that you expect to have the smallest number of items the argument of Intersect().

Upvotes: 8

Lazarus
Lazarus

Reputation: 43074

Not absolutely clear on what you really want here but here's a suggestion for retrieving only the strings that exist in the thingstoSave and existedThings.

IEnumerable<String> existedThings = 
        from mdinfo in mdInfoTotal select mdinfo.ItemNo;

IEnumerable<String> thingsToSave = 
        from item in lbXReadSuccess.Items.Cast<ListItem>() 
        where existedThings.Contains(item.Value)
        select item.Value;

Upvotes: 2

Dan Puzey
Dan Puzey

Reputation: 34198

It's dirty and it also won't work! Your hasItemNo would only be true if the last value in existedThings was in thingsToSave.

Since you tagged this with "Linq", though, I'm guessing this code will work for you:

bool hasItemNo = thingsToSave.Intersect(existedThings).Count() > 0

Upvotes: 3

Darin Dimitrov
Darin Dimitrov

Reputation: 1038790

You may try intersecting the two sequences and see if the resulting sequence contains any elements

Upvotes: 2

Giorgi
Giorgi

Reputation: 30873

bool hasItemNo = existedThings.Intersect(thingsToSave).Count() > 0;

You can even provide your own comparer if you need to: Enumerable.Intersect

Upvotes: 4

Fredrik M&#246;rk
Fredrik M&#246;rk

Reputation: 158309

You can use Intersect to achieve this:

// puts all items that exists in both lists into the inBoth sequence
IEnumerable<string> inBoth = existedThings.Intersect(thingsToSave);

Upvotes: 4

Related Questions