将列表分解为一组索引列表

时间:2016-01-22 19:33:47

标签: c# linq list dictionary

我有一个像这样的类的实例列表。

public class Customer
{
  public Guid Id { get; set; }
  public Guid StoreId { get; set; }
  public string Name { get; set; }
}

我需要通过商店进行分解,以便我有一组列表,其中每个列表包含属于同一商店的所有客户。我试过grouping,但只生成了一个列表列表。我曾经尝试过词典,但是当我需要像Dictionary<Guid, Customer>这样的内容时,这会给我Dictionary<Guid, List<Customer>>。我试着看ILookup甚至是SortedDictionary

最后我感到困惑和模糊。

我希望能够执行这样的迭代。

foreach(KeyValuePair storeWithCustomers in brokenUpList)
{
  DoSomething(storeWithCustomers.Key);
  foreach(Customer customer in storeWithCustomers)
    DoSomething(customer.Name);
}

当然,它不一定是KeyValuePair,并且列表的分解不一定是ToDictionary(尽管它可以,如果它是&#39} ;一个很好的解决方案)。

2 个答案:

答案 0 :(得分:2)

很简单,你只需要这样.GroupBy

foreach(var group in customers.GroupBy(x=>x.StoreId))
{
  DoSomething(group.Key);
  foreach(var customer in group)
    DoSomething(customer.Name);
}

答案 1 :(得分:1)

致电GroupBy后,使用ToDictionary<TSource, TKey> method将分组结果选择为所需类型的Dictionary

请注意,该方法需要两个(lambda)参数(嗯,这里使用的特定重载,至少)。第一个是定义键的选择器(隐式地,它们的类型),第二个定义值(隐式定义它们的类型)。

other answer所示,GroupBy方法将返回IEnumerable<IGrouping<Guid,Customer>>,您可以直接迭代,如下所示:

foreach (IGrouping<Guid, Customer> grp in customers.GroupBy(obj => obj.StoreId))
{
    Guid storeID = grp.Key;
    IEnumerable<Customer> customerCollection = grp;
    foreach (Customer customer in customerCollection)
    {
        // Insert code here.
    }
}

以上可能是更好的方法(例如,如果你的收藏品被懒惰评估,它可能会保留它),但如果这不是你的问题,下面的解决方案会给你完全你所要求的。

在下面的示例中,您可能感兴趣的唯一一行是 last 。其他代码仅仅是为了便于在LinqPad之类的内容中快速运行它以预览结果。

// Just populating some sample data.
List<Guid> storeIDs = new List<Guid>
{
    Guid.NewGuid(),
    Guid.NewGuid(),
    Guid.NewGuid(),
};
List<Customer> customers = new List<Customer>();

customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[0], Name = "John" });
customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[1], Name = "Jacob" });
customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[2], Name = "Schmidt" });
customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[0], Name = "May" });
customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[1], Name = "Naomi" });
customers.Add(new Customer { Id = Guid.NewGuid(), StoreId = storeIDs[2], Name = "Tou" });

// Use the GroupBy method to group the customers by the StoreID
// Then, select the grouped data into a Dictionary.
// Use the StoreID as the key
// To make TValue a List<Customer> call ToList on the IGrouping.
Dictionary<Guid, List<Customer>> result = customers.GroupBy(obj => obj.StoreId).ToDictionary(k => k.Key, v => v.ToList());