【问题标题】:Grouping Dictionary by value using linq使用 linq 按值对字典进行分组
【发布时间】:2012-11-10 20:56:03
【问题描述】:

我有一个字典,将字符串存储为键,将整数存储为表示单词及其出现次数的值。用户需要能够按使用次数或按字母顺序按第一个字母对它们进行排序。尽管我对它很陌生,但我更喜欢使用 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 查询表达式语法。

按字母顺序输出示例:

以a开头的单词:

和冒险一个(等)

按频率输出的示例:

单词出现 1 次:

问题和问题

我正在尝试做的一个不完整的例子:

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

【问题讨论】:

  • 由于您的实际意思似乎有些混乱,请提供一些示例数据 - 您拥有的数据的简要示例,以及您期望输出的样子,而不是添加更多解释关于它。

标签: c# linq dictionary group-by


【解决方案1】:

我对您问题中第一个字母的作用有点困惑...但这将按每个单词的第一个字母分组,然后按该单词的出现次数对组进行排序。

   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()

      };

【讨论】:

  • 我很确定我的答案在那里,但它做得比我需要的多一点,而且让我有点迷失。它只需要按第一个字母或不同时出现的次数进行排序。对不起,我在原始问题中说错了。
【解决方案2】:

如果我理解了问题,那么解决方案是:

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

使用 lambda:

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

GroupBy - 按 Key 第一个字母对 KeyValuePairs 进行分组。

OrderBy - 按字母顺序排列组

【讨论】:

  • 在尝试上面的代码(不是 lambda)时,我收到一个错误“找不到源类型 ___________ 'GroupBy' 的查询模式的植入。我在原始问题中也说错了,我已修复。代码不需要同时按 2 个条件排序。
  • @JamesThompson:在我的示例中,myWordsDictionary 是 Dictionary。你可以使用类似“myWordsDictionary = this.myWords.WordsAsDictionary()”的东西吗?
  • @JamesThompson:我不知道“this.mywords”到底是什么。如果 WordsAsList 返回 List 那么 WordsAsDictionary 应该返回 Dictionary.
  • 好的,我知道了,我想的不对。但我现在明白了。
【解决方案3】:

这是我正在使用的代码。

  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;
  }

【讨论】:

    猜你喜欢
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    相关资源
    最近更新 更多