【问题标题】:IEnumerable<string> to Dictionary<char, IEnumerable<string>>IEnumerable<string> 到 Dictionary<char, IEnumerable<string>>
【发布时间】:2013-06-21 13:48:47
【问题描述】:

我想这个问题可能会部分重复其他类似的问题,但我在这种情况下遇到了麻烦:

我想从一些字符串中提取句子

例如来自

`string sentence = "We can store these chars in separate variables. We can also test against other string characters.";`

我想建立一个 IEnumerable 单词;

var separators = new[] {',', ' ', '.'};

IEnumerable<string> words = sentence.Split(separators, StringSplitOptions.RemoveEmptyEntries);

之后,遍历所有这些words 并将第一个字符放入一个不同的升序字符集合中。

var firstChars = words.Select(x => x.ToCharArray().First()).OrderBy(x => x).Distinct();

之后,遍历这两个集合并为firstChars 中的每个字符从words 中获取所有items,其中first character 等于current character,并创建一个Dictionary&lt;char, IEnumerable&lt;string&gt;&gt; dictionary

我正在这样做:

var dictionary = (from k in firstChars
                  from v in words
                  where v.ToCharArray().First().Equals(k)
                  select new { k, v })
                  .ToDictionary(x => x);

这就是问题所在:An item with the same key has already been added. Whis 是因为在那个字典中它会添加一个现有的字符。

我在查询中加入了GroupBy 扩展

var dictionary = (from k in firstChars
                  from v in words
                  where v.ToCharArray().First().Equals(k)
                  select new { k, v })
                  .GroupBy(x => x)
                  .ToDictionary(x => x);

上面给出的解决方案一切正常,但它给了我比我需要的其他类型。

我应该怎么做才能得到一个 Dictionary&lt;char, IEnumerable&lt;string&gt;&gt;dictionary 但不是 Dictionary&lt;IGouping&lt;'a,'a&gt;&gt;

我想要的结果如下图所示: 但是在这里我必须用 2 个 foreach(s) 进行迭代,这将向我展示我想要的...我无法很好地理解这是怎么发生的...

欢迎任何建议和意见。谢谢。

【问题讨论】:

  • 为什么要写x.ToCharArray().First() 而不是x[0]?为什么要使用Equals() 而不是==
  • @svic,这是一个微不足道的决定 x.ToCharArray().First()x[0] :) Equals() 而不是 == 也具有不重要的相关性。最大的问题是我需要一个 Dictionary&lt;char, IEnumerable&lt;string&gt;&gt; 。所有回复都将我从Dictionary 重定向到ILookup。我试着按照男孩的建议做点什么,但似乎还是遇到了问题。我不需要在控制台上打印结果,而是将该字典发送到另一个需要Dictionary&lt;char, IEnumerable&lt;string&gt;&gt; 输入的接收器:)
  • 我意识到的一件事:您要求Dictionary 中的字符按升序排列。除了不可能之外,Dictionary 的键上没有任何顺序。
  • @svick,好的,它们无法订购,我稍后可以在其他上下文中订购它们
  • 而 p.s.w.g. 答案的第一部分为您提供了一个使用Dictionary 的好方法。

标签: c# linq dictionary ienumerable


【解决方案1】:

由于关系是一对多的,您可以使用查找而不是字典:

var lookup = words.ToLookup(word => word[0]);

loopkup['s'] -> store, separate... as an IEnumerable<string>

如果你想显示按第一个字符排序的键/值:

for (var sortedEntry in lookup.OrderBy(entry => entry.Key))
{
  Console.WriteLine(string.Format("First letter: {0}", sortedEntry.Key);
  foreach (string word in sortedEntry)
  {
    Console.WriteLine(word);
  }
}

【讨论】:

  • 这绝对是比我的建议更好的主意。 +1
【解决方案2】:

你可以这样做:

var words = ...
var dictionary = words.GroupBy(w => w[0])
                      .ToDictionary(g => g.Key, g => g.AsEnumerable());

但是,为什么不使用ILookup

var lookup = words.ToLookup(w => w[0]);

【讨论】:

  • 我同意答案的第一部分,谢谢。所需的结果是 Dictionary> 但不是 ILookup,因为我会将该字典发送到另一个需要 Dictionary> 输入的接收器:)
  • @meorfi 够公平的。我认为如果您的接收器不需要需要从字典中添加/删除项目,它可能应该被重构为使用更简单的界面,但不管怎样都行得通:)——快乐的编码。
  • 我也会考虑重构。谢谢你的建议
猜你喜欢
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多