Linq: В чем разница между Select и Where? - PullRequest
107 голосов
/ 31 июля 2009

Методы Select и Where доступны в Linq. Что должен знать каждый разработчик об этих двух методах? Например: когда использовать один над другим, любые преимущества использования одного над другим и т. Д.

Ответы [ 6 ]

103 голосов
/ 31 июля 2009

Где

находит элементы, которые соответствуют, и возвращает только те, которые соответствуют ( фильтрация ).

-> IEnumerable<A> in, IEnumerable<A> out

Выберите

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

-> IEnumerable<A> in, IEnumerable<B> out

43 голосов
/ 05 августа 2009

Выберите и Где - два совершенно разных оператора, действующих на IEnumerable s.

Первый - это то, что мы называем оператором проецирования , а последний - оператор ограничения .

Один интересный способ понять поведение таких операторов - взглянуть на их «функциональный тип».

  • Выберите: (IEnumerable , Func ) & rarr; IEnumerable <Т2> ; в качестве входных данных он принимает IEnumerable, содержащий элементы типа T1, и функцию, преобразующую элементы типа T1 в элементы типа T2. Выводом является IEnumerable, содержащий элементы типа T2.

    Исходя из этого, можно легко догадаться, что этот оператор выдаст свой вывод, применив функцию ввода к каждому элементу ввода IEnumerable и обернув результаты внутри нового IEnumerable.

    Используя некоторые математические обозначения, он принимает в качестве ввода (a, b, c, ...): IEnumerable и f: T1 & rarr; T2 и производит (f (a), f (b), f (c), ...): IEnumerable

  • Где: (IEnumerable , Func ) & rarr; IEnumerable ; он принимает IEnumerable, содержащий элементы типа T1 и предикат для T1 (то есть функцию, которая выдает логический результат для входа типа T1). Вы видите, что на выходе также есть IEnumerable, содержащий элементы типа T1.

    На этот раз можно было бы предположить, что элемент входного IEnumerable будет присутствовать в выходном IEnumerable в зависимости от результата применения предиката к элементу. Добавив к этому семантику имени оператора, вы можете быть уверены, что он будет выводить IEnumerable, взяв из входного элемента только те элементы, которые оцениваются как true при применении предиката.

Люди с функциональным программированием фон обычно думают так. Это позволяет вам вывести (или, по крайней мере, предположить ...), что делает оператор, только посмотрев на его тип!

В качестве упражнения попробуйте взглянуть на другие операторы, введенные LINQ для IEnumerables, и выясните их поведение, прежде чем просматривать документацию!

40 голосов
/ 31 июля 2009

Они различны:

Select это все о преобразовании .

Where это все о фильтрации .

17 голосов
/ 31 июля 2009

Выберите карты перечислимых для новой структуры. Если вы выполните выбор для IEnumerable, вы получите массив с тем же количеством элементов, но другого типа, в зависимости от указанного вами отображения. Где фильтрует IEnumerable так, что он дает вам подмножество исходного IEnumerable.

7 голосов
/ 22 апреля 2014

Если вы знаете, как они реализовали Where и выбирают методы расширения, вы можете предсказать, что он делает ... Я пытался реализовать где и выбрать методы расширения ... Вы можете посмотреть на это ...

Где реализация ::

public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<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 ) )
        {
            yield return data;
        }
    }
}

Выберите реализацию ::

public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<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)
        yield return Method.Invoke ( item );
    }
}

Моя реализация отлично работает для любой коллекции ... Но она отличается от методов расширения, реализованных Microsoft, поскольку они используют деревья выражений для реализации одного и того же.

6 голосов
/ 28 ноября 2018

Where ~ = Фильтр

Select ~ = Карта

Оба возвращаются IEnumerable<T>

...