2013-10-11 41 views
16

會的SelectMany遍歷對象樹:LINQ SelectMany是綁定?

class Agency { List<Employees> Staff } 

IEnumerable<Agency> Agencies 

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

通常情況下,我總是先挑一局,和工作人員使用的內部情況,以獲得員工。但在政府關閉的情況下,我只想列出每個人看看誰可以覆蓋。

在這種不適合我的對象模型的罕見情況下,我可以使用SelectMany來任意遍歷樹。

你稱之爲遍歷麼?交叉連接?這不是因爲加入已經隱含在機構對象工作人員的組成中。

它是綁定嗎?我不知道有關綁定的任何信息。

有沒有其他名稱選擇,很多?!

+0

SelectMany是地圖。 http://stackoverflow.com/questions/6820866/what-function-acts-as-selectmany-in-jquery –

+3

SelectMany isomorphic綁定。 ' SelectMany的第一個簽名與單一的「綁定」操作符是同構的,在Haskell中寫成>> =。其中一個原因是爲了確立LINQ在已建立的單子架構基礎上的基礎。這個基礎使得LINQ可以適用於各種各樣的事情,比如可組合狀態傳播,異常,延續,替代等等:所有monad。 http://stackoverflow.com/questions/422958/how-c-sharp-compiler-choose-selectmany-when-translating-linq-expression –

+1

相關連接。在SQL Server中,這將是一個'CROSS APPLY'。 – usr

回答

38

SelectMany in C#對應於Scala中的Haskell (>>=)flatMap的綁定。的>>=在Haskell簽名是:

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

所以綁定是用於構建從另一個一元值的操作。

在C#m在上述簽名的情況下是IEnumerableIObservableIQueryable等。IEnumerableSelectMany因此是

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

或C#

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

綁定的含義取決於對於monad類型,對於IEnumerable,輸入序列中的每個元素用於創建一個新序列,並將得到的序列序列展平爲pr輸出輸出序列。

還有另一種配方可能會使這個更清晰。單子通常用綁定的實現來描述,單子還必須支持另外兩個操作,mapjoin

map對應選擇C#,看起來像:

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

所以它是一個「結構保存」在一元價值提升常規功能的方式。

join具有類型

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

所以加入用於壓平嵌套單子值。在C#這看起來像

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

bind可以在地圖方面來實現,並且加入成爲

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

所以要回答原來的問題,SelectMany對應於bindflatMap其他語言。綁定不僅僅是扁平化,而是可以看作是一個變換,然後是嵌套的一元值變平(例如,在IEnumerable<T>的情況下,序列)。 join對於IEnumerable<T>在當前的linq擴展中不存在。

+0

哇。我不明白這裏發生了什麼,但是將IEnumerable與Haskell概念合併的例子給了我一個我能理解的想法。優秀的治療。謝謝。 –

4

在.NET世界之外,它通常被稱爲「扁平化」,如果這就是你要求的。它將二維結果集合平整爲一個維度。

+0

只有兩個維度? SelectMany不會遍歷三層深的樹。 –

+0

它是綁定的嗎?是綁定扁平化? –

+0

不,您在上面的註釋中引用的「綁定」是使Linq語句鏈接在一起的原因。 SelectMany返回一個綁定到下一個鏈接語句的結果的可枚舉(下一個語句作用於結果的可枚舉),下一個語句返回綁定到第三個語句的另一個結果等。 – Dan