Группировка словаря по значению с использованием linq

У меня есть словарь, в котором строки хранятся как ключи, а целые числа — как значения, представляющие слова и количество их повторений. Пользователь должен иметь возможность сортировать их по количеству использований или в алфавитном порядке по 1-й букве. Я бы предпочел использовать LINQ, хотя я новичок в этом. Мне удалось сгруппировать слова на основе начальной буквы, используя следующий код:

public string AlphabeticWordBuilder()
{
    List<String> words = this.myWords.WordsAsList();
    words.Sort();
    return GroupWords(words);
}

private static string GroupWords(List<String> words)
{
    String formatedWords = string.Empty;
    var groups =
        from w in words
        group w by w.First();
    foreach (var group in groups)
    {
        formatedWords += ("\n" + group.Key + ":\n");
        foreach (var w in group)
        {
            formatedWords += (w);
        }
    }
    return formatedWords;
}

Однако этот метод требует, чтобы я преобразовал ключи моего словаря в список, в результате чего я потерял свои значения. Я должен иметь возможность сгруппировать свой словарь по значению аналогичным образом, но я не знаю, как включить отношение ключ/значение в код, который я использую для сортировки по алфавиту. Может ли кто-нибудь опубликовать пример использования LINQ для группировки словаря по значению?

Также я хотел бы избежать синтаксиса метода LINQ и продолжать использовать синтаксис выражения запроса LINQ, показанный выше, если это возможно.

Пример вывода в алфавитном порядке:

Слова, начинающиеся с а:

и приключение (и т.д.)

Пример вывода по частоте:

Слова, встречающиеся 1 раз(а):

вещи и проблемы

Неполный пример того, что я пытаюсь сделать:

public string FrecquincyWordBuilder()
{
    string fromatedWords = string.Empty;
    var groups =
        from w in this.myWords
        group w by w.value;
} 

person James Thompson    schedule 10.11.2012    source источник
comment
Поскольку кажется, что существует некоторая путаница в отношении того, что вы на самом деле имеете в виду, предоставьте некоторые образцы данных - краткий пример того, какие данные у вас есть, и как вы ожидаете, что результат будет выглядеть, вместо того, чтобы добавлять дополнительные пояснения about это.   -  person J. Steen    schedule 11.11.2012


Ответы (3)


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

   var groups =
      from w in this.myWords
      group w by w.Key.First() into g // group by word first letter
      select new { 
            FirstLetter = g.Key, // the group key is the first letter
            WordsWithThisFirstLetter = // order the words with this first letter
                (from wordWithThisFirstLetter in g
                 order by wordWithThisFirstLetter.Value // the number of occurrences of this word
                 select new { 
                         Word = wordWithThisFirstLetter.Key, // dictionary item key 
                         Occurrences = wordWithThisFirstLetter.Value // dictionary item value
                 }
                ).ToArray()

      };
person Jeff    schedule 10.11.2012
comment
Я довольно уверен, что мои ответы там, но он делает немного больше, чем мне нужно, и немного теряет меня. Нужно только сортировать по 1-й букве или по вхождению, а не по обоим одновременно. Извините, что я оговорился в исходном вопросе. - person James Thompson; 11.11.2012

Если я понимаю проблему, то решение:

var groups = from kv in myWordsDictionary
                         group kv by kv.Key.First() into g
                         orderby g.Key
                         select g;

С лямбдой:

var groups = myWordsDictionary.GroupBy(d => d.Key.First()).OrderBy(g => g.Key);

GroupBy - сгруппировать KeyValuePairs по первой букве ключа.

OrderBy - упорядочить группы по алфавиту

person mveith    schedule 10.11.2012
comment
При попытке использовать приведенный выше код (не лямбда) я получаю сообщение об ошибке Не удалось найти имплантацию шаблона запроса для исходного типа ___________ 'GroupBy' не найден. Также я оговорился в исходном вопросе, который я исправил. коду не нужно сортировать сразу по 2 критериям. - person James Thompson; 11.11.2012
comment
@JamesThompson: В моем примере myWordsDictionary — это Dictionary‹string, int›. Можете ли вы использовать что-то вроде myWordsDictionary = this.myWords.WordsAsDictionary()? - person mveith; 11.11.2012
comment
@JamesThompson: я не знаю, что такое this.mywords. Если WordsAsList возвращает List‹string›, тогда WordsAsDictionary должен возвращать Dictionary‹string, int›. - person mveith; 11.11.2012
comment
Хорошо, я понял, я не хочу думать об этом правильно. Но я понял это сейчас. - person James Thompson; 11.11.2012

Это код, который я использую.

  public string FrecquincyWordBuilder()
  {

      string fromatedWords = string.Empty;
      this.myWords.SortByFrequency();
      Dictionary<string, int> wordsAndFec = this.myWords.wordsAsDictionary();
      return GroupWordsByFercs(wordsAndFec);


  }

  private static string GroupWordsByFercs(Dictionary<string, int> wordsAndFec)
  {
      String formatedWords = string.Empty;
      var groups =
          from w in wordsAndFec
          group w by w.Value;
      foreach (var group in groups)
      {
          formatedWords += ("\n Words ocurring " + group.Key + " times:\n");
          foreach (var w in group)
          {
              formatedWords += (w.Key + " ");
          }
      }
      return formatedWords;
  }
person James Thompson    schedule 11.11.2012