2014-04-30 48 views
0

我有一個對象列表(稱爲他們類型salesItems)可以說這些項目有50個屬性,與名稱,價格,數量是其中3個)。我想知道如何合併列表一起使用下面的邏輯通過名稱合併任何salesItems:使用LINQ合併項目在一個集合

如果存在具有相同名稱的多個SalesOrders表:

  • 它們合併成一個SalesOrder具有相同名
  • 設置量的數量
  • 設置價格的總和,並且全部採用的第一

I W值的其他屬性應該喜歡用linq。我意識到我可以使用一個大的每個C#循環來代替。

如果列表中還有其他項目,我想遵循類似的邏輯。

EX: A salesOrder list with (A,B,C,D,E) 

A: Name=ball Price= 2.24 Quantity=1 (other values = bla bla) 
B: Name= ball Price = 15.33 Quantity=3 (other values) 
c: Name= bat Price = 22.14 Quantity=3 (other values) 
D: Name= bat Price= 19.22 Quantity=2 (other values) 
E: Name = ball Price=4.32 Quantity=2 (other values) 

結果列表我要在名單2個銷售訂單(A,C)A:名稱=球價格= 2.24數量= 6(其它值=從屬性BLA BLA)C:名稱=蝙蝠價格= 22.14數量= 5(其它值由C的 屬性)

+0

你爲什麼不顯示你的'SalesItem'類和樣本列表?這會讓你更容易理解。僞「代碼」作爲「列表(A,C)」只是令人困惑。 –

+0

看看Linq的Intersect <>方法... GroupBy也可以在這裏用Distinct()組合來幫助你...雖然你想做的事情的簡短回答是你不會擺脫循環...... LINQ是隻是:幕後循環...但你可以分組你的項目,並使用LINQ儘管對更小的數據集進行更改...... – MaxOvrdrv

+0

你有沒有試圖自己解決這個問題?分享你的代碼! –

回答

5

你想LINQ的.GroupBy方法!

我定義你的類爲:

public class SalesOrder 
{ 
    public string Name { get; set; } 
    public double Price { get; set; } 
    public int Quantity { get; set; } 

    public SalesOrder(string Name, double Price, int Quantity) 
    { 
     this.Name = Name; 
     this.Price = Price; 
     this.Quantity = Quantity; 
    } 
} 

然後我創建了你這樣的訂單列表:

List<SalesOrder> Orders = new List<SalesOrder>() 
{ 
    new SalesOrder("Ball", 2.24, 1), 
    new SalesOrder("Ball", 15.33, 3), 
    new SalesOrder("Bat", 22.14, 3), 
    new SalesOrder("Bat", 19.22, 2), 
    new SalesOrder("Ball", 4.32, 2) 
}; 

,並選擇您想要的值分組之前通過他們的名字對於每個組成SalesOrder類的新實例如下:

List<SalesOrder> Combined_Orders = Orders 
    .GroupBy (o => o.Name) 
    .Select (o => new SalesOrder(o.Key, o.Select (x => x.Price).First(), o.Sum(x => x.Quantity))) 
    .ToList(); 

UPDATE:爲響應OP的評論

由於真正SalesOrder將有上百個屬性,就可以避免在LINQ查詢中輸入他們全部通過添加一個構造函數的SalesOrder類接受羣體的結果作爲一個參數,然後在構造函數中完成所有的工作。雖然它不能阻止你輸入所有的屬性,但它確實意味着它被整齊地抽象出來。這種方式也可以強制/使您決定如何處理每個屬性(第一/總和/平均值)。

要做到這一點,你需要看起來像這樣一個構造:

public SalesOrder(IGrouping<string, SalesOrder> Group) 
    { 
     this.Name = Group.Key; 
     this.Price = Group.First().Price; 
     this.Quantity = Group.Sum(g => g.Quantity); 
     // do all other properties here too 
    } 

然後更新的,看起來像這樣的組(注意,只有分組「G」,結果被傳遞到現在構造函數):

List<SalesOrder> Combined_Orders = Orders 
    .GroupBy (o => o.Name) 
    .Select (g => new SalesOrder(g)) 
    .ToList(); 
+0

這篇文章似乎應該工作,但我想知道的是,如果有什麼辦法可以通過本質上更新現有的銷售訂單對象。這種方法最大的問題是...如果SalesItem類有100個不同的屬性,我必須使用new並從第一個項目(除了數量)命名每個屬性?否則,我會很樂意接受這個解決方案。 – jvoigt

+0

它與普通的LINQ一起工作(我在linqpad中測試過它,它需要對其他類型的LINQ像linq到實體的一些修改)。我不確定你是否能夠至少輸入一次屬性名稱,但是你可以調整構造函數來接受一個組,並且在構造函數中完成所有的工作(I'我會在一分鐘內將它添加到我的答案中) – Ben

+0

我在上面的評論中做了一個錯字,但它現在不會讓我編輯它!我的意思是,我不認爲你可以不用輸入屬性名稱而不用''用' – Ben

0

嗨,您可以使用下面的代碼,

class SalesItem 
{ 
    public string Name { get; set; } 
    public int Price { get; set; } 
    public int Quantity { get; set; } 
} 

class SalesOrder 
{ 
    public void LoadItems() 
    { 
     List<SalesItem> SalesItems = new List<SalesItem>(); 

     SalesItem salesitem = new SalesItem() 
     { 
      Name = "Ball", 
      Price = 12, 
      Quantity = 1 
     }; 

     SalesItems.Add(salesitem); 

     salesitem = new SalesItem() 
     { 
      Name = "Ball", 
      Price = 36, 
      Quantity = 3 
     }; 

     SalesItems.Add(salesitem); 

     salesitem = new SalesItem() 
     { 
      Name = "Bat", 
      Price = 50, 
      Quantity = 1 
     }; 

     SalesItems.Add(salesitem); 

     salesitem = new SalesItem() 
     { 
      Name = "Ball", 
      Price = 84, 
      Quantity = 7    
     }; 

     SalesItems.Add(salesitem); 

     salesitem = new SalesItem() 
     { 
      Name = "Bat", 
      Price = 150, 
      Quantity = 3 
     }; 

     SalesItems.Add(salesitem); 

     GroupOrders(SalesItems); 
    } 

    public List<SalesItem> GroupOrders(List<SalesItem> SalesItems) 
    { 
     var list = from item in SalesItems 
        group item by item.Name into orders 
        select new SalesItem 
        { 
         Name = orders.Key, 
         Price = orders.Sum(X=>X.Price), 
         Quantity = orders.Sum(X=>X.Quantity) 
        }; 

     List<SalesItem> resultList = new List<SalesItem>(); 
     foreach (SalesItem saleitem in list) 
     { 
      resultList.Add(saleitem); 
     } 
     return resultList; 
    } 
} 
+0

OP要求每個組的第一個訂單價格,而不是價格的總和。 – Ben

+0

本是正確的,我希望能使用第一個價格。我確實有另一個問題集中在使用構造函數創建對象。 – jvoigt

+0

你可以做到這一點通過item.Name改變玲查詢,如下,VAR列表=從項目中SalesItems 組項目轉化爲訂單 選擇新SalesItem { 名稱= orders.Key, 價格= orders.First() 。價格, Quantity = orders.Sum(X => X.Quantity) }; – vikasse

相關問題