2013-06-27 63 views
1

我有我想要轉換的項目集合(基本上是包裝在元數據中)。對於集合中的第一個項目,我只是將必要的元數據包裝在項目中,然後完成。第二個項目的元數據依賴於前一個項目的元數據,所以我想將第一個項目的元數據傳遞給第二個項目。因爲它使用object作爲第二輸入,而不是Metadata將當前項目送入LINQ查詢中的下一個項目

下....

object[] A; 

A.skip(1) 
.Zip(A, (first, second), a => new Metadata(first, second)); 

...將無法正常工作。對於我目前看到的其他所有解決方案(傳遞原始對象,而不是Select()函數的結果)都是如此。

我如何將的結果作爲我的LINQ查詢中的第一項輸入Select()的第二項?

我知道我可以使用for循環來實現這一點,但我想知道是否沒有更有效的方式來處理這類問題。必須有功能風格語言(如F#)的解決方案,我想知道是否可以將它轉換爲C#中的LINQ解決方案。單線解決方案尤其令人敬畏。

通過像這樣鏈接元數據,我可以將重要信息從一個項目傳遞到以下所有項目,例如標誌或上下文。最終的目標不僅僅是瞭解上一個項目,而是瞭解當前項目的整個背景。當前項目可以更改所有後續項目的上下文等。

回答

1

這種行爲通常通過函數式編程語言中的scan或類似函數來實現。在F#中,你可以做這樣的:

originalSequence |> Seq.scan (fun (prev, current) -> Some <| new Metadata((* ... stuff ... *))) None 

在C#中的Scan擴展方法的實現見this question。鑑於方法,您可以實現這樣的查詢:

A.Scan((previous, current) => new Metadata(/* ... */), null) 

無法想到的是優雅的單行實施Scan方法的雖然。

+0

謝謝!如果您好奇,我已將此函數應用於[此問題/答案](http://stackoverflow.com/a/17345950/211627)。 – JDB

+0

@ Cyborgx37,很好! – MisterMetaphor

1

嘗試.Aggregate()

var data = A.Aggregate(new Metadata(null, A), (meta, a) => new Metadata(meta, a)); 

我不會保證我擁有該權利的語法,尤其是對於您的代碼。不過,這個想法應該很清楚,如果你編輯一個更徹底的例子,我可以擴展它。

+0

我認爲這是正確的,除了它只會產生序列的最後一個值。 – MisterMetaphor

+0

@MisterMetaphor - 它有[另一個版本](http://msdn.microsoft.com/zh-cn/library/bb548744.aspx)它需要一個函數的額外參數來產生結果。這可能是需要的。另外,感謝您抓住「累積」 - >「聚合」。我一直這樣做。 – Bobson

+0

您可以從方法簽名中看到它也返回單個值。我可能會誤解,但我認爲OP正試圖獲得一系列項目。 – MisterMetaphor

相關問題