2009-06-13 92 views
9

我有一個類型的對象的集合,我想要轉換爲不同的類型。這可以用foreach輕鬆完成,但我想弄清楚如何使用Linq的聚合函數來完成它。如何使用Linq的聚合函數添加到列表C#

問題是所有的聚合示例使用類型行字符串或int,它們支持'+'運算符。我希望累加器類型是一個不支持'+'語義的列表。

這裏有一個簡單的例子:

public class DestinationType 
{ 
    public DestinationType(int A, int B, int C) { ... } 
} 

var set = from item in context.Items 
      select new { item.A, item.B, item.C }; 

var newSet = set.Aggregate(new List<DestinationType>(), 
          (list, item) => list.Add(new DestinationType(item.A, item.B, item.C))); 

的問題是,名單<>。新增返回void。 Aggregate的第二個參數的返回類型需要是List。

如果我有一個支持「+」類型語義列表類型我可以只讓第二個參數

list + item 

但是我找不到支持這種事情任何集合類型。

看起來像這樣應該很容易在Linq中。有沒有辦法?另外,如果我錯過了一個更簡單的方法,我也很想了解這一點。謝謝!

+0

謝謝所有偉大的答案! Sam和Talljoe的答案使用Linq最簡單地完成了。 Thx再次! – Slaggg 2009-06-13 17:50:54

回答

9

我認爲Select加上ToList()的呼叫可能是您在這裏需要的。例如:

context.Items 
    .Select(item => new DestinationType(item.A, item.B, item.C)) 
    .ToList(); 
23

假設這是LINQ到對象,嘗試...

var newSet = set.Aggregate(new List<DestinationType>(), 
            (list, item) => 
            { 
             list.Add(new DestinationType(item.A, item.B, item.C)); 
             return list; 
            }); 
+0

這是正確的做法。 – mquander 2009-06-13 17:20:31

4

你可以只申請select這裏。

var newSet = set.Select(item => new DestinationType(...)).ToList(); 

Aggregate(通常已知爲foldreduce)用於結合元素,其中一起select應用一個函數的每個元素。

例:

f是一元函數,然後 [a, b, c].select(f)等於[f(a), f(b), f(c)]

f是一個二元函數,然後[a, b, c].aggregate(f, init)等於f(a, f(b, f(c, init)))

你在你的例子選擇的方式是在C#中罕見的,但在功能的編程在哪裏(鏈接)的列表轉化爲新的列表,而不是改變現有的集合經常使用:

reversed = fold (\list element -> element:list) [] [1..10] 

如果你真的想用aggregate做這個計算,使用Dustin的解決方案或更好地實現一個基於鏈表的類型爲不可變集合(你甚至可以給這種類型一個operator +)。

3
list.AddRange(context.Items.Select(item => 
    new DestinationType(item.A, item.B, item.C)); 

我意識到它不使用聚合函數,但你應該找一個更好的例子來學習聚合。

1

除非我缺少明顯的東西,爲什麼不只是做:

public class DestinationType 
{ 
    public DestinationType(int A, int B, int C) { ... } 
} 

var newSet = from item in context.Items 
    select new DestinationType(item.A, item.B, item.C);