LINQ SelectMany является связыванием? - программирование
Подтвердить что ты не робот

LINQ SelectMany является связыванием?

SelectMany будет перемещаться по дереву объектов:

class Agency { List<Employees> Staff }

IEnumerable<Agency> Agencies

IEnumerable<Employee> =  
from anAgency in Agencies  
from anEmployee in anAgency.Staff. 
select anEmployee; 

Обычно я всегда выбираю Агентство сначала и использую внутренний экземпляр Персонала для получения сотрудников. Но в случае закрытия правительства я просто хочу перечислить ВСЕ, чтобы узнать, кто может покрыть.

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

Как вы называете это обход? перекрестное соединение? Дело не в том, что соединение уже подразумевается в составе персонала в объекте Агентства.

Связано ли это? Я ничего не знаю о bind.

Нет ли другого имени, кроме Select, Many?!

4b9b3361

Ответ 1

SelectMany в С# соответствует привязка в Haskell (>>=) или flatMap в Scala. Подпись >>= в Haskell:

(>>=) :: Monad m => m a -> (a -> m b) -> m b

поэтому bind - это операция, используемая для построения одного монадического значения из другого.

В случае С# m в вышеуказанной сигнатуре IEnumerable, IObservable, IQueryable и т.д. Для IEnumerable, SelectMany, следовательно,

IEnumerable<A> -> (A -> IEnumerable<B>) -> IEnumerable<B>

или в С#

public static IEnumerable<B> SelectMany<A, B>(this IEnumerable<A> first, Func<A, IEnumerable<B>> selector)

Значение bind зависит от типа monad, для IEnumerable каждый элемент во входной последовательности используется для создания новой последовательности, а результирующая последовательность последовательностей сглаживается для создания выходной последовательности.

Существует еще одна формулировка связывания, которая может сделать это более ясным. Хотя монады часто описываются с точки зрения реализации bind, монады также должны поддерживать две другие операции: map и join.

map соответствует Select в С# и выглядит так:

map :: Monad m => (a -> b) -> (ma -> m b)

так что это "сохраняющий структуру" способ поднятия регулярной функции над монадическим значением.

join имеет тип

join :: Monad m => m m a -> m a

поэтому join используется для выравнивания вложенных монадических значений. В С# это будет выглядеть как

public static IEnumerable<A> Join<A>(this IEnumerable<IEnumerable<A>> nested)

bind может быть реализован в терминах карты и присоединения как

m >>= f = join (map f m)

поэтому для ответа на исходный вопрос SelectMany соответствует bind или flatMap на других языках. Привязка не просто сглаживается, но может рассматриваться как преобразование, за которым следует сглаживание вложенных монадических значений (например, последовательности в случае IEnumerable<T>). join для IEnumerable<T> не существует в текущих расширениях linq.

Ответ 2

Из мира .NET он часто называется "сглаживанием", если это то, о чем вы просите. Он выравнивает двумерный результирующий набор в одно измерение.