Lambda expressions and LINQ
Здравейте колеги,
решавам някои задачи от темата за "Dictionaries, Lambda and LINQ" и на всяка задача общо взето където трябва да подреждам или вадя някаква информация с Lambda expressions and LINQ се мъча доста. Последно забих на 07. Population Counter и не мога да реша задачата, само защото не мога да изкарам Output-a по начина по който се иска. Това така не може да продължава и се изнервям. За това искам да ви помоля да ми дадете съвети/насоки + информация какво и къде да чета/гледам за да се науча да работя по-добре с Lambda expressions and LINQ защото те са основи, които задължително трябва да се знаят много добре, а аз някъде нещо бъркам явно. Имам записани сигурно всички основни LINQ методи, и знам кой какво прави, но като трябва да ги навързвам и става пълен мармалад. Опитвам се да мисля логично, но ето на на последната задача трябва да обработя Dictionary<string, Dictionary<string, long>>(); и след около 1 час мъчене, не успях...
Моля помагайте и кажете какво и къде да чета/гледам, защото в книгата на Наков няма много по тази тема, 2 лекции гледах за тази тема, но в самата лекция се разглеждам основно кой метод какво прави и се навързват някакви много лесни примери. Докато в домашните има доста по-сложни заявки които трябва да се обработят и аз не мога да се спрая.
Надявам се да получа помощ по тази тема, благодаря ви!
EDIT: за да се придобие по-добра представа на нивото ми на разбиране на този материал давам следния пример:
1. Мое решенеие за Output-a на предната задача "User logs":
var orderedUsernameAndIp = usernameAndIp.OrderBy(n => n.Key);
StringBuilder printResult = new StringBuilder();
foreach (var user in orderedUsernameAndIp)
{
Console.WriteLine("{0}:", user.Key);
foreach (var ip in user.Value)
{
printResult.AppendFormat("{0} => {1}, ", ip.Key, ip.Value);
}
printResult.Remove((printResult.Length - 2), 2);
printResult.Insert(printResult.Length, '.');
Console.WriteLine(printResult);
printResult.Clear();
}
2. Същият Output но от решение, което видях от един друг колега и което за мен е немислимо да се сетя как да го направя по този начин. Когато го гледам, си го обеснявам горе долу, но да успея да се сетя за него и да го напиша няма шанс.
foreach (var user in users)
{
Console.WriteLine($"{user.Key}:");
Console.WriteLine(string.Join(", ", user.Value.Select(value => value.Key + " => " + value.Value).ToArray()) + ".");
}
В dotnetperls имат приятно обяснение, но отново стигаме до това, че са твърде елементарни примерите им. Нещата, които обесняват там са от сорта на: ArrayOne.Selec(n => n.ToLower());, и пише Select обхожда всеки елемент в колекцията и прилага метода ToLower на него, което на мен ми е ясно и не ми помага никак.
Виж когато имаме списък Dictionary<string, Dictionary<string, long>>(); и трябва да изкараме резултат "city|country|population", като всяка country има N на брой градове и всеки град брой жители. Трябва да ги подредим държавите по descending order според общата популация на градовете им, после градовете се подреждат под всяка държава по същия начин. И ако има град или държава с равен брой население, се изписват в реда в който са въведени на конзолата. Ето това е пример на сложна за мен Lambda операция, която не мога да изпълня. Опитите ми представляват нещо от порядъка на:
var result = finalStatistic.OrderByDescending(n => n.Value.Select(m => m.Value).Sum());
- моето обяснение на горния израз е такъв: вземи всеки Value (т.е. Dictionary<string, long>) и селектирай всеки Value (т.е. всеки long) и събраната колекция, сумирай. Като OrderByDescending, би трябвало да ги подреди по тази сума.
Но както можете да се досетите, този израз не прави това, което искам, а именно да подреди държавите според общата им популация.