selectmany - select method c#
LINQ SelectMany es vinculante? (2)
SelectMany atravesará un árbol de objetos:
class Agency { List<Employees> Staff }
IEnumerable<Agency> Agencies
IEnumerable<Employee> =
from anAgency in Agencies
from anEmployee in anAgency.Staff.
select anEmployee;
Por lo general, siempre escogería una Agencia primero y usaría la instancia interna de Personal para obtener los empleados. Pero en el caso de un cierre del gobierno, solo quiero enumerar a TODOS para ver quién puede cubrir.
En este caso raro que no es apropiado para mi modelo de objetos, puedo usar SelectMany para atravesar arbitrariamente el árbol.
¿Cómo llamas a esto transversal? una unión cruzada? No es porque la unión ya esté implícita en la composición del Personal en el objeto de la Agencia.
Es vinculante? No sé nada sobre el enlace.
¿No tiene otro nombre que Select, Many ?
Fuera del mundo .NET, a menudo se lo llama "aplanamiento", si eso es lo que estás preguntando. Se aplana un conjunto de resultados bidimensionales en una sola dimensión.
SelectMany
en C # corresponde vincular en Haskell (>>=)
o flatMap
en Scala. La firma de >>=
en Haskell es:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
así que bind es una operación utilizada para construir un valor monádico a partir de otro.
En el caso de C # m
en la firma anterior es IEnumerable
, IObservable
, IObservable
, etc. Para IEnumerable
, SelectMany
es por lo tanto
IEnumerable<A> -> (A -> IEnumerable<B>) -> IEnumerable<B>
o en C #
public static IEnumerable<B> SelectMany<A, B>(this IEnumerable<A> first, Func<A, IEnumerable<B>> selector)
El significado de vinculación depende del tipo de mónada, para IEnumerable, cada elemento de la secuencia de entrada se utiliza para crear una nueva secuencia, y la secuencia de secuencias resultante se aplana para producir la secuencia de salida.
Hay otra formulación de enlace que puede aclarar esto. Mientras que las mónadas a menudo se describen en términos de su implementación de vinculación, las mónadas también deben admitir otras dos operaciones, map
y join
.
map
corresponde a Seleccionar en C # y se ve así:
map :: Monad m => (a -> b) -> (ma -> m b)
por lo tanto, es una manera de "preservar la estructura" de elevar una función regular sobre un valor monádico.
join
tiene el tipo
join :: Monad m => m m a -> m a
así que join se usa para aplanar los valores monádicos anidados. En C # esto se vería como
public static IEnumerable<A> Join<A>(this IEnumerable<IEnumerable<A>> nested)
bind
se puede implementar en términos de mapa y unirse como
m >>= f = join (map f m)
SelectMany
, para responder a la pregunta original, SelectMany
corresponde a bind
o flatMap
en otros idiomas. La vinculación no es solo aplanamiento, sino que puede verse como una transformación seguida por un aplanamiento de valores monádicos anidados (por ejemplo, secuencias en el caso de IEnumerable<T>
). join
para IEnumerable<T>
no existe en las extensiones linq actuales.