#c# #linq
#c# #linq
Вопрос:
У меня есть Dictionary
, CustomerInfo_Dict
, который хранит CustomerID (Key) | Age (Value)
-
Получить distinct
Age (Value)
-
Добавьте совпадающую
CustomerID (Key)
базу для каждого отдельногоAge (Value)
вArray/List/other type
foreach (var CustomerInfo_Dict_DistinctAge in CustomerInfo_Dict.Values.Distinct()) { foreach (var CustomerInfo in CustomerInfo_Dict) { //if (CustomerInfo <Value>:Age) == (CustomerInfo_Dict_DistinctAge <Value>:Age) { //add matched `CustomerID (Key)` to a separate List } } }
Комментарии:
1. Итак, вы хотите поменять местами свой словарь? Создать словарь, который сопоставляет возраст-> список идентификаторов с этим возрастом?
Ответ №1:
Требуется только один цикл (не LINQ)
var ageToIds = new Dictionary<int, List<int>>();
foreach(var kvp in idToAge){
if(!ageToIds.ContainsKey(kvp.Value))
ageToIds[kvp.Value] = new List<int>();
ageToIds[kvp.Value].Add(kvp.Key);
}
И с помощью LINQ мы можем заставить LINQ создать группу по значению (возрасту), которое станет ключом, и вся KeyValuePair станет списком значений (из которого мы затем можем выбрать только ключ.. но обратите внимание, что это ключ KeyValuePair, а не ключ группировки):
var ageToIds = idToAge
.GroupBy(kvp => kvp.Value)
.ToDictionary(
g => g.Key,
g => g.Select(kvp => kvp.Key).ToList()
);
Возможно, вы даже сможете пропустить часть словаря, потому что игрофикация Linq — это почти то же самое:
var ageToIdsGrouping = idToAge
.GroupBy(kvp => kvp.Value, kvp => kvp.Key);
Это дает вам GroupedEnumerable, который похож на словарь, если вы его перечисляете; это коллекция группировок, каждая группировка имеет ключ (который является возрастом) и сама является перечислимым из целых чисел (которые являются идентификаторами)
foreach(var g in ageToIdsGrouping){
int age = g.Key;
var ids = g; //it's an enumerable list of the IDs
string idsString = string.Join(',', ids);
Console.WriteLine($"{age}: {idsString}");
}
Если у вас было это раньше:
idToAge[123] = 30;
idToAge[234] = 30;
idToAge[345] = 30;
idToAge[456] = 31;
У вас должно быть это:
ageToIds[30] = { 123, 234, 345 };
ageToIds[31] = { 456 };
Чтобы получить все списки:
foreach(var kvp in ageToIds){
int age = kvp.Key;
List<int> ids = kvp.Value;
}
Комментарии:
1. Спасибо! Я пытаюсь использовать вашу версию, отличную от LINQ. Я вижу, что вы добавили
value
в anew List
, если в ключе нет совпадения. После запуска я получаю все созданные списки, перебирая каждый ключforeach(var kvp in idToAge)
, чтобы получить всеageToIds[kvp.Value]
созданные списки? * извинения, я хотел сказать, что я не могу придумать метод получения всех созданных списков после выполнения вышеуказанного.