Как я комбинирую ключи и значения Словаря в один Список с помощью LINQ?

Может быть, это видео поможет, Brain Carns столкнулся с теми же проблемами и исправил это: https://www.youtube.com/watch?v=bROui4ID9_Q

или вы можете посмотреть at: Flutter: сборка не удалась с исключением

6
задан Andy 15 April 2009 в 19:28
поделиться

5 ответов

A Solution in C#

Here is a solution using the aggregate extension method:

string result = values.Aggregate("",
                  (keyString, pair) =>
                    keyString + "\n" + pair.Key + ":"
                      + pair.Value.Aggregate("",
                          (str, val) => str + "\n\t" + val)
                  );

There is no LINQ syntax for the aggregate clause in C# (but apparently there is in Visual Basic for some predefined functions).

This solution might look somewhat complex, but the aggregate method is quite useful.

How Aggregate works

It works like this: If you have a List you can combine all values into a single aggregate value.

That is in contrast to the Select method, which doesn't modify the length of the list. Or the Where method, which does shrink the list, but it still remains a list (instead of a single value).

For example, if you have a list {1, 2, 3, 4} you can combine them into a single value like this:

int[] xs = {1, 2, 3, 4};
int sum = xs.Aggregate(0, (sumSoFar, x) => sumSoFar + x);

So you give two values to the Aggregate method; a seed value and a 'combiner' function:

  • You start aggregating with a single seed value (0 in this case).
  • Your combiner function gets called for each value in the list.
    Первым аргументом является вычисленный результат до настоящего времени (ноль в первый раз, позже он будет иметь другие значения), и он объединяет его со значением x .

Вкратце, как Aggregate метод работает с List . Он работает так же на KeyValuePair > , но только с разными типами.

20
ответ дан 8 December 2019 в 04:55
поделиться

Я не уверен, как бы вы сделали это в LINQ, но используя лямбды, вы могли бы сделать что-то вроде:

string foo = string.Join(Environment.NewLine, 
    values.Select(k => k.Key + Environment.NewLine + 
        string.Join(Environment.NewLine, 
            k.Value.Select(v => "\t" + v).ToArray())).ToArray());

Хотя это не очень хорошо читается.

2
ответ дан 8 December 2019 в 04:55
поделиться

Я бы сделал выбор значений, чтобы поместить вещи в начальный список по элементам (используя string.Join для значения), а затем вставьте его в строку (снова используя string.Join).

IEnumerable<string> items = values.Select(v => 
    string.Format("{0}{1}{2}", v.Key, Environment.NewLine + "\t", 
    string.Join(Environment.NewLine + "\t", v.Value.ToArray()));
string itemList = string.Join(Environment.NewLine, items.ToArray());
0
ответ дан 8 December 2019 в 04:55
поделиться

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

Даже если это не так, в лучшем случае, LINQ поможет вам просто получить один источник перечисления для циклического переключения, который вы бы сделали в любом случае необходимо иметь какую-то логику разделения, чтобы указывать, когда вы обрабатываете набор значений по сравнению с ключом.

Суть в том, что у уже имеющегося словаря есть естественная группировка, которой LINQ не будет может помочь больше, если только вы не имеете дело с какой-либо операцией, кроме группировки (сортировка, проекция, фильтрация).

1
ответ дан 8 December 2019 в 04:55
поделиться

Если бы у вас был такой метод:

public IEnumerable<string> GetStrings
  (KeyValuePair<string, List<string>> kvp)
{
  List<string> result = new List<string>();
  result.Add(kvp.Key);
  result.AddRange(kvp.Value.Select(s => "\t" + s));
  return result;
}

Тогда вы могли бы сделать это:

List<string> result = theDictionary
  .SelectMany(kvp => GetStrings(kvp)).ToList();

Или в общем случае:

public static IEnumerable<T> GetFlattened<T, U>
  ( this KeyValuePair<T, List<U>> kvp,
    Func<U, T> ValueTransform
  )
{
  List<T> result = new List<T>();
  result.Add(kvp.Key);
  result.AddRange(kvp.Value.Select(v => ValueTransform(v)));
  return result;
}

List<string> result = theDictionary
  .SelectMany(kvp => kvp.GetFlattened(v => "\t" + v))
  .ToList();
1
ответ дан 8 December 2019 в 04:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: