SelectИ Whereметоды доступны в Linq. Что каждый разработчик должен знать об этих двух методах? Например: когда использовать одно над другим, какие преимущества от использования одного над другим и т. Д.
Я не думаю, что этот вопрос следует помечать как CW, возможно, на него есть однозначный ответ.
Брэндон
1
@Brandon, нет ничего плохого в том, чтобы отмечать что-то CW, если это объективно.
Rex M
@Rex, я согласен. Просто скажу, что на разницу между Select и Where есть однозначный ответ, а вторая часть вопроса, скорее всего, будет основана на общепринятых практиках. Я просто указывал на это на тот случай, если ОП не был уверен в том, чтобы пометить вещи как CW. Если он действительно хотел, чтобы это было CW, то меня это устраивает.
Брэндон
6
В этом много плохого. CW бесполезен, и становится все более бесполезным, когда люди помечают вопросы как CW совершенно случайно
jalf
Ответы:
127
куда
находит совпадающие элементы и возвращает только те, которые соответствуют ( фильтрация ).
-> IEnumerable<A>внутрь, IEnumerable<A>наружу
Выбрать
возвращает что-то для всех элементов в источнике ( проекция / преобразование ). Это что-то может быть самими предметами, но чаще всего это своего рода проекция.
Selectвсегда будет возвращать одинаковое количество элементов в списке (независимо от условий фильтрации, которые у вас могут быть). Whereможет возвращать меньше элементов в зависимости от условий вашего фильтра.
По крайней мере, для меня, имея некоторый опыт работы с другими языками, это помогает думать об этом Where == filterиSelect == map
bgusach
52
Select и Where - два совершенно разных оператора, действующих на IEnumerable .
Первый - это то, что мы называем оператором проекции , а последний - оператор ограничения .
Один интересный способ понять поведение таких операторов - взглянуть на их «функциональный тип».
Выберите: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; на вход он принимает как IEnumerable, содержащий элементы типа T1, так и функцию, преобразующую элементы типа T1 в элементы типа T2. Результатом является IEnumerable, содержащий элементы типа T2.
Исходя из этого, легко догадаться, что этот оператор будет производить свой вывод, применяя функцию ввода к каждому элементу входного IEnumerable и помещая результаты в новый IEnumerable.
Используя некоторые математические обозначения, он принимает в качестве входных данных (a, b, c, ...): IEnumerable <T1> и f: T1 → T2 и производит (f (a), f (b), f (c) , ...): IEnumerable <T2>
Где: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; этот принимает IEnumerable, содержащий элементы типа T1 и предикат на T1 (то есть функцию, которая производит логический результат для ввода типа T1). Вы видите, что вывод также является IEnumerable, содержащим элементы типа T1.
На этот раз можно было бы предположить, что элемент входного IEnumerable будет присутствовать в выходном IEnumerable в зависимости от результата применения предиката к элементу. Добавляя к этому семантику имени оператора, вы можете быть уверены, что он создаст выходной IEnumerable, взяв из входного только те элементы, которые оцениваются как истинные при применении предиката.
Люди с опытом функционального программирования обычно так думают. Это позволяет вам вывести (или хотя бы догадаться ...), что делает оператор, только взглянув на его тип!
В качестве упражнения попробуйте взглянуть на другие операторы, представленные LINQ в IEnumerables, и вывести их поведение, прежде чем просматривать документацию!
Select отображает перечислимый объект в новую структуру. Если вы выполните выбор в IEnumerable, вы получите массив с тем же количеством элементов, но другого типа в зависимости от указанного вами сопоставления. Где фильтрует IEnumerable, чтобы получить подмножество исходного IEnumerable.
Если вы знаете, как они реализовали методы расширения Where и select, вы можете предсказать, что он делает ... Я попытался реализовать где и выбрать методы расширения ... Вы можете взглянуть на это ...
Где реализация:
publicstaticIEnumerable<Tsource>Where<Tsource>(thisIEnumerable<Tsource> a ,Func<Tsource,bool>Method){foreach(var data in a ){//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)if(Method.Invoke( data )){yieldreturn data;}}}
Выберите реализацию ::
publicstaticIEnumerable<TResult>Select<TSource,TResult>(thisIEnumerable<TSource> a ,Func<TSource,TResult>Method){foreach(var item in a ){//Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)yieldreturnMethod.Invoke( item );}}
Моя реализация отлично работает для любой коллекции ... Но она отличается от методов расширения, реализованных Microsoft, потому что они используют деревья выражений для реализации того же.
Ответы:
куда
находит совпадающие элементы и возвращает только те, которые соответствуют ( фильтрация ).
->
IEnumerable<A>
внутрь,IEnumerable<A>
наружуВыбрать
возвращает что-то для всех элементов в источнике ( проекция / преобразование ). Это что-то может быть самими предметами, но чаще всего это своего рода проекция.
->
IEnumerable<A>
внутрь,IEnumerable<B>
наружуисточник
Select
всегда будет возвращать одинаковое количество элементов в списке (независимо от условий фильтрации, которые у вас могут быть).Where
может возвращать меньше элементов в зависимости от условий вашего фильтра.select
и вот один дляwhere
Where == filter
иSelect == map
Select и Where - два совершенно разных оператора, действующих на IEnumerable .
Первый - это то, что мы называем оператором проекции , а последний - оператор ограничения .
Один интересный способ понять поведение таких операторов - взглянуть на их «функциональный тип».
Выберите: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; на вход он принимает как IEnumerable, содержащий элементы типа T1, так и функцию, преобразующую элементы типа T1 в элементы типа T2. Результатом является IEnumerable, содержащий элементы типа T2.
Исходя из этого, легко догадаться, что этот оператор будет производить свой вывод, применяя функцию ввода к каждому элементу входного IEnumerable и помещая результаты в новый IEnumerable.
Используя некоторые математические обозначения, он принимает в качестве входных данных (a, b, c, ...): IEnumerable <T1> и f: T1 → T2 и производит (f (a), f (b), f (c) , ...): IEnumerable <T2>
Где: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; этот принимает IEnumerable, содержащий элементы типа T1 и предикат на T1 (то есть функцию, которая производит логический результат для ввода типа T1). Вы видите, что вывод также является IEnumerable, содержащим элементы типа T1.
На этот раз можно было бы предположить, что элемент входного IEnumerable будет присутствовать в выходном IEnumerable в зависимости от результата применения предиката к элементу. Добавляя к этому семантику имени оператора, вы можете быть уверены, что он создаст выходной IEnumerable, взяв из входного только те элементы, которые оцениваются как истинные при применении предиката.
Люди с опытом функционального программирования обычно так думают. Это позволяет вам вывести (или хотя бы догадаться ...), что делает оператор, только взглянув на его тип!
В качестве упражнения попробуйте взглянуть на другие операторы, представленные LINQ в IEnumerables, и вывести их поведение, прежде чем просматривать документацию!
источник
Они различны:
Select
все о трансформации .Where
все о фильтрации .источник
Select отображает перечислимый объект в новую структуру. Если вы выполните выбор в IEnumerable, вы получите массив с тем же количеством элементов, но другого типа в зависимости от указанного вами сопоставления. Где фильтрует IEnumerable, чтобы получить подмножество исходного IEnumerable.
источник
Where
~ = ФильтрSelect
~ = КартаОба возвращения
IEnumerable<T>
источник
Если вы знаете, как они реализовали методы расширения Where и select, вы можете предсказать, что он делает ... Я попытался реализовать где и выбрать методы расширения ... Вы можете взглянуть на это ...
Где реализация:
Выберите реализацию ::
Моя реализация отлично работает для любой коллекции ... Но она отличается от методов расширения, реализованных Microsoft, потому что они используют деревья выражений для реализации того же.
источник
В случае Select вы можете сопоставить IEnumerable новой структуры.
Where () работает как фильтр для IEnumerable, он вернет результат на основе предложения where.
источник