C# 这是使用LINQ创建频率表的最佳方法吗?

C# 这是使用LINQ创建频率表的最佳方法吗?,c#,linq,C#,Linq,我想写一个函数,读取一个文件并计算每个单词出现的次数。假设处理了文件读取并生成了表示文件中每一行的字符串列表,我需要一个函数来计算每个单词的出现次数。首先,使用字典是最好的方法吗?关键字是单词,值是该单词出现的次数 我编写了这个函数,它迭代每一行和每一行中的每个单词,并建立一个字典: static IDictionary<string, int> CountWords(IEnumerable<string> lines) var dict = new Dictionary

我想写一个函数,读取一个文件并计算每个单词出现的次数。假设处理了文件读取并生成了表示文件中每一行的字符串列表,我需要一个函数来计算每个单词的出现次数。首先,使用
字典
是最好的方法吗?关键字是单词,值是该单词出现的次数

我编写了这个函数,它迭代每一行和每一行中的每个单词,并建立一个字典:

static IDictionary<string, int> CountWords(IEnumerable<string> lines)
var dict = new Dictionary<string, int>();
foreach (string line in lines)
{
    string[] words = line.Split(' ');
    foreach (string word in words)
    {
        if (dict.ContainsKey(word))
            dict[word]++;
        else
            dict.Add(word, 1);
    }
}
静态IDictionary CountWords(IEnumerable行)
var dict=新字典();
foreach(行中的字符串行)
{
string[]words=line.Split(“”);
foreach(单词中的字符串)
{
if(dict.ContainsKey(word))
dict[单词]+;
其他的
dict.Add(单词,1);
}
}
但是,我想以某种方式编写这个函数。。在功能上,使用LINQ(因为LINQ很有趣,我正在努力提高我的功能编程技能:D)我成功地提出了这个表达式,但我不确定这是否是功能上最好的方法:

static IDictionary<string, int> CountWords2(IEnumerable<string> lines)
{
    return lines
        .SelectMany(line => line.Split(' '))
        .Aggregate(new Dictionary<string, int>(),
            (dict, word) =>
            {
                if (dict.ContainsKey(word))
                    dict[word]++;
                else
                    dict.Add(word, 1);
                return dict;
            });
}
静态IDictionary countwords 2(IEnumerable行)
{
回程线
.SelectMany(line=>line.Split(“”))
.Aggregate(新字典(),
(dict,word)=>
{
if(dict.ContainsKey(word))
dict[单词]+;
其他的
dict.Add(单词,1);
返回命令;
});
}

因此,虽然我有两个可行的解决方案,但我也有兴趣了解解决这个问题的最佳方法。任何对LINQ和FP有深入了解的人?

请查看
GroupBy
而不是
Aggregate
——它将为您提供一组
i分组
对象。您可以通过对每个分组调用
.count()
来检索每个单词的计数。

正如Tim Robinson所写,您可以像这样使用
GroupBy
ToDictionary

    public static Dictionary<string, int> CountWords3(IEnumerable<string> strings)
    {
        return strings.SelectMany(s => s.Split(' ')).GroupBy(w=>w).ToDictionary(g => g.Key, g => g.Count());
    }
公共静态字典CountWords3(IEnumerable字符串)
{
返回strings.SelectMany(s=>s.Split(“”)).GroupBy(w=>w.ToDictionary(g=>g.Key,g=>g.Count());
}

以下各项应能完成此工作

static IDictionary<String, Int32> CountWords(IEnumerable<String> lines)
{
    return lines
        .SelectMany(line => line.Split(' '))
        .GroupBy(word => word)
        .ToDictionary(group => group.Key, group => group.Count());
}
静态IDictionary CountWords(IEnumerable行)
{
回程线
.SelectMany(line=>line.Split(“”))
.GroupBy(word=>word)
.ToDictionary(group=>group.Key,group=>group.Count());
}
如果要使用linq(而不是使用linq firectly使用的扩展方法),可以编写:

var groups = from line in lines
             from s in line.Split(new []{"\t", " "},StringSplitOptions.RemoveEmptyEntries) 
             group s by s into g
             select g;
var dic = groups.ToDictionary(g => g.Key,g=>g.Count());

您当前的实现不会在选项卡上拆分,可能会包含“word”字符串。为空,因此我已根据我认为您的意图更改了拆分。

顺便说一句,既然您说您对学习感兴趣,我没有发布确切的代码:)谢谢,你的提示让我玩得更多,做得更好:)从技术上讲,这不是通过使用语言集成查询,而是通过使用LINQ所建立的一些扩展方法(但是OP要求使用LINQ,但使用扩展方法,所以这可能是他要求的:)@Rune FS:都是LINQ,使用查询理解语法还是扩展方法语法取决于个人偏好。(事实上,有些查询只能用扩展方法语法来表达。你会说那些查询不是LINQ吗?@Rune FS:我想他是在问linqish这样做的方法。正如LukeH指出的,这都是LINQ的问题。在Tim Robinson暗示使用GroupBy后,我自己设法解决了这个问题。这基本上就是我完成的查询。@Luke。我决不会声称调用方法就是使用语言集成查询。但是,如果查询与该语言集成,比如说是否使用了一种特殊的语法来调用这些方法(例如,从xs中的x选择x:)