2016-01-22 2 views
1

У меня есть список экземпляров такого класса.Разбиение списка в набор индексированных списков

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 (хотя она может, если это хорошее решение).

+1

Вы хотите набор списков, но список списков не в порядке? Какие? –

+1

Как «GroupBy» не дает вам именно то, что вам нужно? Результаты этого уровня прекрасно согласуются с тем, что вы говорите, что хотите сделать с ним. – krillgar

+0

В связанном ответе оператор 'Select' отбрасывает информацию группировки и возвращает список списков. Использование 'GroupBy' - это то, что вы хотите. –

ответ

2

Простой, вам просто нужно .GroupBy как это:

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

@ Давай! Действительно хорошо поставил! Я взял на себя смелость вставить это в ваш ответ, потому что я определенно нашел бы это полезным, если бы я исследовал и ударил по этому вопросу. Не стесняйтесь отмечать этот комментарий как obso. –

1

Используйте ToDictionary<TSource, TKey> method после вызова GroupBy для выбора сгруппированных результатов в Dictionary нужного типа.

Обратите внимание, что метод принимает два параметра (лямбда) (ну, конкретная перегрузка, используемая здесь, по крайней мере). Первый - это селектор, который определяет ключи (и неявно, их тип), а второй определяет значения (также неявно определяя их тип).

Как показано в 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()); 
Смежные вопросы