2015-06-03 45 views
1

所以,我有以下幾點:將3個列表比較和重新組合成一個列表?

class Item 
{ 
    string Name; 
    bool IsSelected; 
} 

而且我有3個表:

List<Item> list1; 
List<Item> list2; 
List<Item> list3; 

我的目標是上述轉換成一個單一的集合,其中類似的「項目」對象組合在一起(類似=具有相同「名稱」的對象)。

所以我想:

List<ItemContainer> resultantList; 

其中:

class ItemContainer 
{ 
    string Name; 
    IList<Item> items; //items with the same 'Name' (potentially) 
} 

注:

  • 列表可以有不同數量的項目。
  • 「Item」對象只能屬於一個列表。只是我們可以在不同的列表中使用相同的「名稱」具有不同的對象。
  • 如果沒有找到具有相同「名稱」的其他對象,則仍然需要將 包含在結果列表中。

什麼是最簡潔和最明確的實現方式?

注意:性能不是問題。

感謝您的幫助。

+0

'ItemContainer'有一個'Name'屬性嗎? –

+0

是的,你是對的。我更新了我的代碼。 – alhazen

+0

你嘗試過什麼嗎?用LINQ做這件事非常簡單,但即使是一個foreach循環也會這樣做...... – MarcinJuraszek

回答

3

你可以試試GroupBy

var groupyName = list1.Concat(list2).Concat(list3).GroupBy(I => I.Name); 
+1

然後只是'foreach(var groupyName)''。 'g.Key'將成爲你的'名字',你可以爲你的'物品'創建一個'新名單(g)'。 –

1

這是爲了做到這一點:

itemContainer.items = list1.Concat(list2).Concat(list3) 
        .Distinct() 
        .OrderBy(item => item.Name) 
        .ThenByDescending(item => item.IsSelected) 
        .ToList(); 

這裏是你問什麼是完整的例子,
不要注意到你不需要GroupBy,因爲分組的返回值與您希望收到的新列表不相同。

你需要重寫Item方法GetHashCode()Equals(object obj)Distinct()會自動使用這些項目之間的比較。

class Program 
    { 
     static void Main(string[] args) 
     { 
      var list1 = new List<Item> 
      { 
       new Item {Name = "A", IsSelected = true}, 
       new Item {Name = "B", IsSelected = false}, 
       new Item {Name = "C", IsSelected = true} 
      }; 

      var list2 = new List<Item> 
      { 
       new Item {Name = "A", IsSelected = true}, 
       new Item {Name = "C", IsSelected = true}, 
       new Item {Name = "D", IsSelected = false} 
      }; 

      var list3 = new List<Item> 
      { 
       new Item {Name = "B", IsSelected = true}, 
       new Item {Name = "E", IsSelected = false}, 
       new Item {Name = "F", IsSelected = false} 
      }; 

      var itemContainer = new ItemContainer(); 
      itemContainer.items = list1.Concat(list2).Concat(list3) 
       .Distinct() 
       .OrderBy(item => item.Name) 
       .ThenByDescending(item => item.IsSelected) 
       .ToList(); 

      //new list of items will contain 7 items: 
      // A,true 
      // B,true 
      // B,false 
      // C,true 
      // D,false 
      // E,false 
      // F,false 
     } 
    } 

    public class Item 
    { 
     public string Name; 
     public bool IsSelected; 

     public override int GetHashCode() 
     { 
      return Name.GetHashCode() * IsSelected.GetHashCode(); 
     } 

     public override bool Equals(object obj) 
     { 
      var objItem = obj as Item; 
      return objItem != null && objItem.Name == Name && objItem.IsSelected == IsSelected; 
     } 
    } 

    public class ItemContainer 
    { 
     public string Name; 
     public IList<Item> items; //items with the same 'Name' (potentially) 
    }