pixartist
pixartist

Reputation: 1155

Select items from multiple lists via linq

I have the following issue:

class Base
{
   int val;
}
class A : Base
{
}
class B : Base
{
}

//Now I want to select from list of a and b
List<A> aList;
List<B> bList;
IEnumerable<Base> Find(int i)
{
//would need something like this
  return from a in (aList and bList) where a.val == i select a as Base;
}

What would be the fastest solution for this ? Should I join the enumerations afterwards or is that possible within the linq query ?

edit: Would .Concat be the quickest way ?

Upvotes: 1

Views: 1397

Answers (3)

Eric J.
Eric J.

Reputation: 150108

You can use Union

return from a in (aList.Union<Base>(bList)) where a.val == i select a as Base;

Produces the set union of two sequences by using the default equality comparer.

http://msdn.microsoft.com/en-us/library/vstudio/bb341731(v=vs.100).aspx

UPDATE

Union will return all of the unique elements in both lists (that is, if the same element were in both lists, only one of them would be returned

The Concat(IEnumerable, IEnumerable) method differs from the Union method because the Concat(IEnumerable, IEnumerable) method returns all the original elements in the input sequences. The Union method returns only unique elements.

http://msdn.microsoft.com/en-us/library/vstudio/bb302894(v=vs.100).aspx

If this behavior is not desired, use Concat

return from a in (aList.Concat<Base>(bList)) where a.val == i select a as Base;

Upvotes: -1

jlew
jlew

Reputation: 10591

How about:

return lista.Cast<Base>().Concat(listb).Where( x => x.val == i);

Cast<Base> is necessary to have a list of homogenous types, and Concat is the same as Union but will not incur the overhead of duplicate elimination.

Upvotes: 3

David
David

Reputation: 10708

First off, use a .OfType method to cast everything and allow each collection to be the same type. This will only perform an explicit cast on objects already of the desired type, and return only objects of the desired type - I find it perfect for upcasting situations like this.

The second collection does not need to be cast, however - because of the definition of IEnumerable<out T> uses out you can allow polymorphism to act on the second collection properly. See Covariance and Contravariance for more info on this behaviour.

If you want everything returned regardless of comparison, use .Concat

aList.OfType<Base>()
.Contat(bList)

If you want each item returned only once, use .Union

aList.OfType<Base>()
.Union(bList)

I Personally recommend Concat over Union, since it simply returns every element, whereas Union does the overhead of checking for duplicates, a task better suited to the .Distnict Method

Upvotes: 0

Related Questions