Wha*_*sit 2 c# linq lookup dictionary data-structures
将数据转换IEnumerable
为类似查询或字典的结构的最佳方法是什么,但每个值有多个键?
我正在寻找的东西与此大致相同,并且以通用的方式:
var wordsByLetter = new Dictionary<char, HashSet<string>>();
foreach (string word in words)
{
foreach (char letter in word.Distinct())
{
if (!wordsByLetter.ContainsKey(letter))
{
wordsByLetter.Add(letter, new HashSet<string>());
}
wordsByLetter[letter].Add(word);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,结果是一个字典映射用于包含该字母的单词集的每个字母.
例如,如果words
包含,{"foo", "faz", "zoo"}
则生成的字典将包含:
'a' -> {"faz"}
'f' -> {"foo", "faz"}
'o' -> {"foo", "zoo"}
'z' -> {"faz", "zoo"}
Run Code Online (Sandbox Code Playgroud)
我可以将我的代码示例转换为扩展方法,但是是否有内置函数或更好的算法可供使用?
ToLookup是您需要的扩展方法.例如:
var lookup = (from word in words
from c in word
select new { Word = word, Character = c }).ToLookup(x => x.Character, x => x.Word);
Run Code Online (Sandbox Code Playgroud)
这是一个解决方案ToDictionary
:
var wordsByLetter =
words.SelectMany(word => word.ToCharArray())
.Distinct()
.ToDictionary(
letter => letter,
letter => words.Where(word => word.Contains(letter)));
Run Code Online (Sandbox Code Playgroud)
请注意,它肯定比你的代码效率低,因为单词集合被枚举一次以获得不同的字母,然后每个字母一次......
更新:实际上我有一个更有效的建议:
var wordsByLetter =
(from word in words
from letter in word
group word by letter into grp
select new
{
Letter = grp.Key,
Words = new HashSet<string>(grp)
})
.ToDictionary(x => x.Letter, x => x.Words);
Run Code Online (Sandbox Code Playgroud)
它应该提供与您的代码完全相同的结果