昨晚无意间想到 Leetcode 刷道题,因为太久没刷就随便挑了道 Easy 的题来玩玩,顺便用用 C#。在这个过程中试了试 C# 中的 Linq 特性,果然好用到爆。
使用的场景为,需要对数组里面的不同元素分别进行计数,如:
1
2
3
4
5
6
7
8
9
| var arr = new List<string>{"cat", "bat","rat","dog","cat","cat","rat"};
var count = CountEle(arr);
// should return
// {
// "cat": 3,
// "bat": 1,
// "rat": 2,
// "dog": 1
// }
|
最为常规的方法当然就是遍历计数了
1
2
3
4
5
6
7
8
9
10
| Dictionary<string,int> CountEle(List<string> arr)
{
var result = new Dictionary<string,int>();
foreach(var word in arr)
{
if(result.ContainsKey(word)) result[word]++;
else result.Add(word,1);
}
return result;
}
|
这样的方法简单直接,但是我对于在遍历时里面还要对于是否包含元素进行一次判断,要多写一个判断,多写一个语句感到不爽,就想着搜搜有没改进的办法,像是在 Python 里面,就可以通过 setdefault 或者 get 方法来避免键值还不存在的情况。
然后发现了 Linq 的方法,起飞。Linq 的方法思路大概就是将可遍历的元素用 Sql 的方法来处理,还是挺爽挺直观的。
1
2
3
4
5
6
7
8
9
10
| Dictionary<string,int> CountEle(List<string> arr)
{
var groups = arr.GroupBy(s => s)
.Select(s => new {
Word => s.Key,
Count => s.Count()
});
return groups.ToDictionary(s=>s.Word,s=>s.Count);
}
|
最后送上一个 Python 版本更加 tricky 的方法。
1
| CountEle = lambda arr: {i:arr.count(i) for i in set(arr)}
|