2014-10-16 6 views
1

У меня есть следующий вопрос:Выбор элементов из нескольких списков с помощью LINQ

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; 
} 

Что будет самым быстрым решением для этого? Должен ли я присоединиться к перечислениям позже или это возможно в запросе linq?

Редактировать: Был бы .Конкат быстрей?

ответ

-1

Вы можете использовать союз

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

объединение множеств из двух последовательностей, используя компаратор равенство по умолчанию.

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

UPDATE

Союз будет возвращать все уникальные элементы в обоих списках (то есть, если тот же элемент был в обоих списках, только один из них будет возвращено

Метод Concat (IEnumerable, IEnumerable) отличается от метода Union, потому что метод Concat (IEnumerable, IEnumerable) возвращает все оригинальные элементы nts во входных последовательностях. Метод Union возвращает только уникальные элементы.

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

Если такое поведение нежелательно, использовать Concat

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

Я не думаю, что скомпилируем. – jlew

+0

Будет ли это быстрее, чем Конкат? Кроме того, могу ли я использовать объединение с двумя разными типами списков? – pixartist

+0

Не было бы дешевле сделать, где по обоим спискам и объединить результаты? – DavidG

0

Во-первых, используйте метод .OfType, чтобы бросить все и позволить каждой коллекции, чтобы быть того же типа. Это приведет только к явному приложению объектов, которые уже имеют желаемый тип, и возвращают только объекты желаемого типа - я считаю, что это идеально подходит для таких ситуаций, как это происходит.

Вторая коллекция не требуется, однако, из-за определения IEnumerable<out T> используется out, вы можете разрешить полиморфизм действовать на вторую коллекцию правильно. См. Covariance and Contravariance для получения дополнительной информации об этом поведении.

Если вы хотите, чтобы все вернулись независимо от сравнения, использовать .Concat

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

Если вы хотите, чтобы каждый элемент возвращается только один раз, использовать .Union

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

Лично я рекомендую Concat над Union, так как это просто возвращает каждый элемент, тогда как Union выполняет накладные расходы на проверку дубликатов, задача лучше подходит для .Distnict Method

3

Как насчет:

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

Cast<Base> необходим иметь список однородных типов, и Concat такие же, как Союз, но не будет нести накладные расходы устранения дублирования.

+2

Вам действительно нужно только одно из отливок – Jonesopolis

+0

Вы правы, исправлены. – jlew

+0

Вы также можете использовать 'Concat ' вместо актеров. –

Смежные вопросы