Os métodos Selecte Whereestão disponíveis no Linq. O que todo desenvolvedor deve saber sobre esses dois métodos? Por exemplo: quando usar um sobre o outro, quaisquer vantagens de usar um sobre o outro, etc.
Eu não acho que essa pergunta deva ser marcada como CW, poderia ter uma resposta definitiva.
Brandon
1
@Brandon, não há nada de errado em marcar algo como CW, se for objetivo.
Rex M
@Rex, eu concordo. Apenas dizendo que a diferença entre Select e Where tem uma resposta definitiva, e a segunda parte da pergunta provavelmente se baseará em práticas comumente aceitas. Eu estava apenas apontando no caso de o OP não ter certeza sobre marcar as coisas como CW. Se ele pretendia que fosse CW, tudo bem para mim.
Brandon
6
Há muita coisa errada nisso. CW é inútil, e ficando mais quando as pessoas marcar perguntas completamente ao acaso, como CW
jalf
Respostas:
126
Onde
localiza itens que correspondem e retorna apenas aqueles que correspondem ( filtragem ).
-> IEnumerable<A>dentro, IEnumerable<A>fora
Selecione
retorna algo para todos os itens na fonte ( projeção / transformação ). Que algo pode ser os itens em si, mas geralmente são uma projeção de algum tipo.
Selectsempre retornará o mesmo número de elementos na lista (independentemente da condição de filtro que você possa ter). Wherepode retornar menos elementos, dependendo da condição do filtro.
Goku_da_master
E aqui é um exemplo MSDN de selecte aqui é um parawhere
yazanpro
Pelo menos para mim, ter algum fundo com outras línguas, ele ajuda a pensar que Where == filtereSelect == map
bgusach
52
Selecione e Onde estão dois operadores completamente diferentes atuando em IEnumerable s.
O primeiro é o que chamamos de Operador de Projeção , enquanto o último é um Operador de Restrição .
Uma maneira interessante de entender o comportamento desses operadores é dar uma olhada no seu "tipo funcional".
Selecione: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; toma como entrada um IEnumerable contendo elementos do tipo T1 e uma função que transforma elementos do tipo T1 em elementos do tipo T2. A saída é um IEnumerable contendo elementos do tipo T2.
A partir disso, pode-se adivinhar com facilidade que esse operador produzirá sua saída aplicando a função de entrada em cada elemento da entrada IEnumerable e agrupando os resultados dentro de um novo IEnumerable.
Usando um pouco de matemática-como notação, que toma como entrada (a, b, c, ...): IEnumerable <T1> e f: T1 → T2 e produz (f (a), f (b), f (c) , ...): IEnumerable <T2>
Onde: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; este pega um IEnumerable contendo elementos do tipo T1 e um predicado em T1 (ou seja, uma função que produz um resultado booleano para uma entrada do tipo T1). Você vê que a saída também é um IEnumerable contendo elementos do tipo T1.
Desta vez, seria de supor que um elemento da entrada IEnumerable estará presente na saída IEnumerable, dependendo do resultado da aplicação do predicado ao elemento. Adicionando a isso a semântica do nome do operador, você pode ter certeza de que ele produzirá a saída IEnumerable, retirando da entrada apenas os elementos que são avaliados como verdadeiros na aplicação do predicado.
Pessoas com experiência em programação funcional geralmente pensam assim. Permite deduzir (ou pelo menos adivinhar ...) o que um operador faz apenas olhando seu tipo!
Como exercício, tente examinar outros operadores introduzidos pelo LINQ no IEnumerables e deduzir seu comportamento, antes de examinar a documentação!
Selecione mapeia um enumerável para uma nova estrutura. Se você executar uma seleção em um IEnumerable, obterá uma matriz com o mesmo número de elementos, mas um tipo diferente, dependendo do mapeamento especificado. Onde filtra o IEnumerable para fornecer um subconjunto do IEnumerable original.
Se você sabe como eles implementaram o Where e selecione os métodos de extensão, você pode prever o que está fazendo ... Tentei implementar o where e selecione os métodos de extensão ... Você pode dar uma olhada nele ...
Onde Implementação ::
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;}}}
Selecione a implementação ::
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 );}}
Minha implementação funciona bem para qualquer coleção ... Mas difere dos métodos de extensão implementados pela Microsoft, porque eles usam árvores de expressão para implementar o mesmo.
Respostas:
Onde
localiza itens que correspondem e retorna apenas aqueles que correspondem ( filtragem ).
->
IEnumerable<A>
dentro,IEnumerable<A>
foraSelecione
retorna algo para todos os itens na fonte ( projeção / transformação ). Que algo pode ser os itens em si, mas geralmente são uma projeção de algum tipo.
->
IEnumerable<A>
dentro,IEnumerable<B>
forafonte
Select
sempre retornará o mesmo número de elementos na lista (independentemente da condição de filtro que você possa ter).Where
pode retornar menos elementos, dependendo da condição do filtro.select
e aqui é um parawhere
Where == filter
eSelect == map
Selecione e Onde estão dois operadores completamente diferentes atuando em IEnumerable s.
O primeiro é o que chamamos de Operador de Projeção , enquanto o último é um Operador de Restrição .
Uma maneira interessante de entender o comportamento desses operadores é dar uma olhada no seu "tipo funcional".
Selecione: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; toma como entrada um IEnumerable contendo elementos do tipo T1 e uma função que transforma elementos do tipo T1 em elementos do tipo T2. A saída é um IEnumerable contendo elementos do tipo T2.
A partir disso, pode-se adivinhar com facilidade que esse operador produzirá sua saída aplicando a função de entrada em cada elemento da entrada IEnumerable e agrupando os resultados dentro de um novo IEnumerable.
Usando um pouco de matemática-como notação, que toma como entrada (a, b, c, ...): IEnumerable <T1> e f: T1 → T2 e produz (f (a), f (b), f (c) , ...): IEnumerable <T2>
Onde: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; este pega um IEnumerable contendo elementos do tipo T1 e um predicado em T1 (ou seja, uma função que produz um resultado booleano para uma entrada do tipo T1). Você vê que a saída também é um IEnumerable contendo elementos do tipo T1.
Desta vez, seria de supor que um elemento da entrada IEnumerable estará presente na saída IEnumerable, dependendo do resultado da aplicação do predicado ao elemento. Adicionando a isso a semântica do nome do operador, você pode ter certeza de que ele produzirá a saída IEnumerable, retirando da entrada apenas os elementos que são avaliados como verdadeiros na aplicação do predicado.
Pessoas com experiência em programação funcional geralmente pensam assim. Permite deduzir (ou pelo menos adivinhar ...) o que um operador faz apenas olhando seu tipo!
Como exercício, tente examinar outros operadores introduzidos pelo LINQ no IEnumerables e deduzir seu comportamento, antes de examinar a documentação!
fonte
Eles são distintos:
Select
é tudo sobre transformação .Where
é tudo sobre filtragem .fonte
Selecione mapeia um enumerável para uma nova estrutura. Se você executar uma seleção em um IEnumerable, obterá uma matriz com o mesmo número de elementos, mas um tipo diferente, dependendo do mapeamento especificado. Onde filtra o IEnumerable para fornecer um subconjunto do IEnumerable original.
fonte
Where
~ = FiltroSelect
~ = MapaAmbos retornos
IEnumerable<T>
fonte
Se você sabe como eles implementaram o Where e selecione os métodos de extensão, você pode prever o que está fazendo ... Tentei implementar o where e selecione os métodos de extensão ... Você pode dar uma olhada nele ...
Onde Implementação ::
Selecione a implementação ::
Minha implementação funciona bem para qualquer coleção ... Mas difere dos métodos de extensão implementados pela Microsoft, porque eles usam árvores de expressão para implementar o mesmo.
fonte
No caso de Selecionar, você pode mapear para um IEnumerable de uma nova estrutura.
Where () funciona como um filtro para o IEnumerable, ele retornará o resultado com base na cláusula where.
fonte