Linq: В чем разница между Select и Where

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

Ответ 1

Где

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

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

Выбрать

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

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

Ответ 2

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

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

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

  • Выберите: (IEnumerable < T1 > , Func < T1, T2 > ) → IEnumerable < Т2 > ; он принимает в качестве входных как 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, взяв из входного только те элементы, которые оценивают true при применении предиката.

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Where ~ = Фильтр

Select ~ = Карта

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

Ответ 6

Если вы знаете, как они реализовали 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 методов расширения, потому что они используют деревья выражений для реализации того же самого.

Ответ 7

В случае выбора его вы можете сопоставить IEnumerable новой структуры.

  A.Select(x=>new X{UID=x.uid, UNAME=x.uname}) 
  //input as [IEnumerable<A>] -------->  return output as [IEnumerable<X> ]

Где() работает как фильтр для IEnumerable, он возвращает результат на основе предложения where.

A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] -------->  return output as [IEnumerable<A> ]