2013-02-20 103 views
0

我有一個List<Item>Item具有屬性Id,NameAmount。這個列表中有重複的項目。我需要得到一個新的List<Item>,其中只包含非重複的Item s和ItemAmount應該是它在第一個List<Item>中複製多少次的數量。我試過類似從列表中刪除<>重複的項目和重複的數量

  for (int i = 0; i < list.Count; i++) 
      { 
       for (int j = 0; j < list.Count; j++) 
       { 
         if (list[i].Name == list[j].Name) 
         { 
          list.Remove(prod.Components[j]); 
          list[i].Amount++; 
         } 
       } 
      } 

但是在這個循環中有一些問題。我的大腦過熱。請幫忙。

+0

什麼在你的背景下複製?只是id或id和名字? – VladL 2013-02-20 10:41:48

+0

@VladL ID和名稱 – user1947702 2013-02-20 10:42:48

+0

你怎麼知道'prod.Components [j]'存在?而你沒有考慮你的移動指數。 – 2013-02-20 10:44:26

回答

1

一個簡單的LINQ查詢,可以讓你的獨特的項目用的次數一起出現:

var distinct = list.GroupBy(o => o.Name) 
        .Select(g => new { Count = g.Count(), Item = g.First() }) 
        .ToList(); 

然後,你可以修改每個項目的Amount到重複的次數:

foreach (var row in distinct) 
{ 
    row.Item.Amount = row.Count; 
} 

最後找回一個List<Item>,其中不包含重複項並且數量正確:

var uniqueItems = distinct.Select(r => r.Item).ToList(); 

重要提示:上面的代碼假設「重複」項目彼此不可區分,但沒有其他任何內容(例如,它不需要Item有一個默認的構造函數)。根據具體情況,可能會以更短的形式編寫它。

此外,Amount屬性在這裏看起來很奇怪。由於重複項不能保證金額的總和,Item.Amount的目的是什麼?我會假設數量爲2的重複項目應該導致一個項目的數量爲4,但是你的代碼不會這樣做(並且我的跟隨導致)。

+0

謝謝,它的工作原理!) – user1947702 2013-02-20 10:55:40

0

關閉我的頭頂部(沒有測試過):

list.GroupBy(x => x.Name) 
    .Select(x => new Item { 
          Name = x.Key, 
          Amount = x.Count() 
          }) 
    .ToList(); 

您還沒有指定什麼發生了IDS,所以我離開不理他們。

(注意,這會創建一個新列表,而不是修改原始列表)。

0

嘗試類似的東西:

var groups = from item in items 
      group item by item.Property 
      into grouped 
      select grouped; 

var distinct = from g in groups 
       let item = g.First() 
       let amount = g.Count() 
       select new Item {Property = item.Property, Amount = amount}; 

之後distinct包含IEnumerable<Item>從原來的項目列表中的量。

0

假設您確定前兩個屬性IDName的重複項。

你可以實現一個IEqualityComparer<Item>,並用這些Enumerable.GroupBy

var itemAmounts = items.GroupBy(i => i, new Item()) 
    .Select(g => new Item { 
     ID = g.First().ID, 
     Name = g.First().Name, 
     Amount = g.Count() 
    }); 

這是你的項目類有意義的實施IEqualityComparer<Item>

class Item : IEqualityComparer<Item> 
{ 
    public int ID; 
    public string Name; 
    public int Amount; 

    public bool Equals(Item x, Item y) 
    { 
     if (x == null || y == null) return false; 

     bool equals = x.ID == y.ID && x.Name == y.Name; 
     return equals; 
    } 

    public int GetHashCode(Item obj) 
    { 
     if (obj == null) return int.MinValue; 

     int hash = 19; 
     hash = hash + obj.ID.GetHashCode(); 
     hash = hash + obj.Name.GetHashCode(); 
     return hash; 
    } 
} 

你也可以從object覆蓋EqualsGetHasdhCode,那麼你根本不需要自定義比較器:GroupBy

var itemAmounts = items.GroupBy(i => i) 
    .Select(g => new Item { 
     ID = g.First().ID, 
     Name = g.First().Name, 
     Amount = g.Count() 
    }); 

您可以使用上面已經可用的方法:

public override bool Equals(object obj) 
{ 
    Item item2 = obj as Item; 
    if (item2 == null) 
     return false; 
    else 
     return Equals(this, item2); 
} 

public override int GetHashCode() 
{ 
    return GetHashCode(this); 
} 
0
foreach(var item in list) 
{ 
    if(list.Count(e=>e.Id == item.Id && e.Name == item.Name)!=1) 
    { 
     list.Remove(item); 
    } 
}