C# C linq累加
我需要得到一个枚举值的总和。请参见此示例: 在这一来源中:C# C linq累加,c#,linq,C#,Linq,我需要得到一个枚举值的总和。请参见此示例: 在这一来源中: namespace ConsoleApplication { enum fruits { Orange, Grape, Papaya } class item { public fruits fruit; public string foo; } class Program { static void Main(string[] args
namespace ConsoleApplication
{
enum fruits { Orange, Grape, Papaya }
class item
{
public fruits fruit;
public string foo;
}
class Program
{
static void Main(string[] args)
{
item[] list = new item[]
{
new item() { fruit = fruits.Orange, foo = "afc" },
new item() { fruit = fruits.Orange, foo = "dsf" },
new item() { fruit = fruits.Orange, foo = "gsi" },
new item() { fruit = fruits.Orange, foo = "jskl" },
new item() { fruit = fruits.Grape, foo = "mno" },
new item() { fruit = fruits.Grape, foo = "pqu" },
new item() { fruit = fruits.Grape, foo = "tvs" },
};
var vTotals = from... //Here
}
}
}
我想全部都是
类型
我怎么能和Linq一起做
提前感谢您在这里要做的是逻辑上的群组加入。您希望使用表示每个水果的序列连接此表,然后计算这些组的大小
var totals = Enum.GetValues(typeof(fruits)).OfType<fruits>()
.GroupJoin(list,
fruit => fruit,
item => item.fruit,
(fruit, group) => new { Key = fruit, Value = group.Count() })
.ToDictionary(pair => pair.Key, pair => pair.Value);
这里要做的是逻辑上的组联接。您希望使用表示每个水果的序列连接此表,然后计算这些组的大小
var totals = Enum.GetValues(typeof(fruits)).OfType<fruits>()
.GroupJoin(list,
fruit => fruit,
item => item.fruit,
(fruit, group) => new { Key = fruit, Value = group.Count() })
.ToDictionary(pair => pair.Key, pair => pair.Value);
您可以将所有水果类型的组联接用于以下项目:
var vTotals = from fruits f in Enum.GetValues(typeof(fruits))
join i in list on f equals i.fruit into g
select new {
Fruit = f,
Count = g.Count()
};
结果:
[
{ Fruit: "Orange", Count: 4 },
{ Fruit: "Grape", Count: 3 },
{ Fruit: "Papaya", Count: 0 }
]
您可以将所有水果类型的组联接用于以下项目:
var vTotals = from fruits f in Enum.GetValues(typeof(fruits))
join i in list on f equals i.fruit into g
select new {
Fruit = f,
Count = g.Count()
};
结果:
[
{ Fruit: "Orange", Count: 4 },
{ Fruit: "Grape", Count: 3 },
{ Fruit: "Papaya", Count: 0 }
]
这里有一个方法。这也许不如在一个查询中完成所有的工作那么漂亮,但我很清楚:代码的第一部分要感谢谁,谁删除了他的答案
var vTotals = list.GroupBy(i => i.fruit)
.ToDictionary(g => g.Key, g => g.Count());
foreach (var fruit in Enum.GetValues(typeof(fruits)).Cast<fruits>()
.Where(x => !vTotals.ContainsKey(x)))
{
vTotals.Add(fruit, 0);
}
这里有一个方法。这也许不如在一个查询中完成所有的工作那么漂亮,但我很清楚:代码的第一部分要感谢谁,谁删除了他的答案
var vTotals = list.GroupBy(i => i.fruit)
.ToDictionary(g => g.Key, g => g.Count());
foreach (var fruit in Enum.GetValues(typeof(fruits)).Cast<fruits>()
.Where(x => !vTotals.ContainsKey(x)))
{
vTotals.Add(fruit, 0);
}
这应该可以
var vTotals = list.GroupBy(item => item.fruit)
.Select(item => Tuple.Create(item.Key, item.Count()))
.ToDictionary(key => key.Item1, value => value.Item2);
在这里,我们只需将水果名称与它们的计数进行分组,然后将其编入字典即可
var vTotals = list.GroupBy(item => item.fruit)
.Select(item => Tuple.Create(item.Key, item.Count()))
.ToDictionary(key => key.Item1, value => value.Item2);
在这里,如果您想使用MSTest进行单元测试,我们只需将水果名称与它们的计数进行分组,然后将其从@Servy的答案转换为字典
[TestClass]
public class DummyTests {
[TestMethod]
public void GroupCountByFruitType() {
// arrange
var expected = new Dictionary<Fruits, int>() {
{ Fruits.Grape, 3 }
, { Fruits.Orange, 4 }
, { Fruits.Papaya, 0 }
};
Item[] list = new Item[] {
new Item() { Fruit = Fruits.Orange, Foo = "afc" },
new Item() { Fruit = Fruits.Orange, Foo = "dsf" },
new Item() { Fruit = Fruits.Orange, Foo = "gsi" },
new Item() { Fruit = Fruits.Orange, Foo = "jskl" },
new Item() { Fruit = Fruits.Grape, Foo = "mno" },
new Item() { Fruit = Fruits.Grape, Foo = "pqu" },
new Item() { Fruit = Fruits.Grape, Foo = "tvs" }
};
// act
var actual = Enum.GetValues(typeof(Fruits)).OfType<Fruits>()
.GroupJoin(list
, fruit => fruit
, item => item.Fruit
, (fruit, group) => new { Key = fruit, Value = group.Count() })
.ToDictionary(pair => pair.Key, pair => pair.Value);
// assert
actual.ToList()
.ForEach(item => Assert.AreEqual(expected[item.Key], item.Value));
}
private class Item {
public Fruits Fruit { get; set; }
public string Foo { get; set; }
}
private enum Fruits {
Grape,
Orange,
Papaya
}
}
根据@Servy的回答,如果您想使用MSTest对其进行单元测试
[TestClass]
public class DummyTests {
[TestMethod]
public void GroupCountByFruitType() {
// arrange
var expected = new Dictionary<Fruits, int>() {
{ Fruits.Grape, 3 }
, { Fruits.Orange, 4 }
, { Fruits.Papaya, 0 }
};
Item[] list = new Item[] {
new Item() { Fruit = Fruits.Orange, Foo = "afc" },
new Item() { Fruit = Fruits.Orange, Foo = "dsf" },
new Item() { Fruit = Fruits.Orange, Foo = "gsi" },
new Item() { Fruit = Fruits.Orange, Foo = "jskl" },
new Item() { Fruit = Fruits.Grape, Foo = "mno" },
new Item() { Fruit = Fruits.Grape, Foo = "pqu" },
new Item() { Fruit = Fruits.Grape, Foo = "tvs" }
};
// act
var actual = Enum.GetValues(typeof(Fruits)).OfType<Fruits>()
.GroupJoin(list
, fruit => fruit
, item => item.Fruit
, (fruit, group) => new { Key = fruit, Value = group.Count() })
.ToDictionary(pair => pair.Key, pair => pair.Value);
// assert
actual.ToList()
.ForEach(item => Assert.AreEqual(expected[item.Key], item.Value));
}
private class Item {
public Fruits Fruit { get; set; }
public string Foo { get; set; }
}
private enum Fruits {
Grape,
Orange,
Papaya
}
}
我认为这不包括papayas@Selman22会的。GroupJoin的条目数始终与第一个集合中的条目数相同。@Servy那么这将转换为GroupJoin或Join吗?这是如何执行左侧外部联接的?@Selman22它将被转换为组联接。除了Sergey遗漏了ToDictionary调用之外,该代码将准确地转换为我的答案中所示的代码。组联接从第二个序列为第一个序列中的每个项创建一组匹配项。该组可以为空。我不认为这将包括papayas@Selman22会的。GroupJoin的条目数始终与第一个集合中的条目数相同。@Servy那么这将转换为GroupJoin或Join吗?这是如何执行左侧外部联接的?@Selman22它将被转换为组联接。除了Sergey遗漏了ToDictionary调用之外,该代码将准确地转换为我的答案中所示的代码。组联接从第二个序列为第一个序列中的每个项创建一组匹配项。这一组可以是空的。这比前两个答案的效率要低一些,因为你要对第一个答案中的每一项进行第二个集合的线性搜索。这比前两个答案的效率要低一些,因为您正在对第一个集合中的每个项目对第二个集合进行线性搜索。这将不包括木瓜。这将不包括木瓜。如果实际实现是var-actual=new Dictionary;它已经通过了你的测试。我也不认为发布一个现有答案的简单测试用例是对问题的真正回答。@Servy:是的。我只是因为.NET惯例而使用大写字母。OP可能更喜欢使用小写。只是想让你知道,我+1你的答案,因为我从来没有用这种方式与Linq分组。不知怎的,我看到了一些新的东西=如果实际实现是var-actual=newdictionary;它已经通过了你的测试。我也不认为发布一个现有答案的简单测试用例是对问题的真正回答。@Servy:是的。我只是因为.NET惯例而使用大写字母。OP可能更喜欢使用小写。只是想让你知道,我+1你的答案,因为我从来没有用这种方式与Linq分组。不知怎的,我看到了一些新的东西=