我有一个如下所示的数据集:
[
{
"Size" : "Small",
"Details" :
{
"Detail 1" : 1.0,
"Detail 1" : 1.0,
"Detail 2" : 1.0,
}
},
{
"Size" : "Small",
"Details" :
{
"Detail 1" : 2.0,
"Detail 1" : 3.0,
"Detail 2" : 4.0,
}
},
{
"Size" : "Medium",
"Details" :
{
"Detail 1" : 1.0,
"Detail 1" : 1.0,
"Detail 2" : 1.0,
"Detail 3" : 1.0,
}
},
//... etc
]
对于具有相同“大小”的所有项目,我想单独总结匹配的“详细信息”条目,然后像“大小”d 项目一样对它们进行平均。IE:
[
{
"Size" : "Small",
"Details" :
{
"Detail 1" : 3.5,
"Detail 2" : 2.5, // Average of the summation of the two 'small' items in original data set
},
{
"Size" : "Medium",
"Details" :
{
"Detail 1" : 2.0, // Average of the two details for medium.
"Detail 2" : 1.0,
"Detail 3" : 1.0,
}
},
]
我得到的代码就是这样,但我一直在弄清楚如何在嵌套集中进行平均。任何指针将不胜感激。
我的代码,到目前为止。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class ItemWithDetails
{
public string Size;
public List<KeyValuePair<string, double>> Details { get; private set; }
public ItemWithDetails(string size)
{
Size = size;
Details.Add(new KeyValuePair<string, double>("Detail 1", 1));
Details.Add(new KeyValuePair<string, double>("Detail 1", 1));
Details.Add(new KeyValuePair<string, double>("Detail 2", 1));
Details.Add(new KeyValuePair<string, double>("Detail 2", 1));
Details.Add(new KeyValuePair<string, double>("Detail 2", 1));
Details.Add(new KeyValuePair<string, double>("Detail 3", 1));
if (size == "Large")
{
Details.Add(new KeyValuePair<string, double>("Detail 3", 1));
Details.Add(new KeyValuePair<string, double>("Detail 3", 1));
Details.Add(new KeyValuePair<string, double>("Detail 3", 1));
}
}
}
class Program
{
static void Main(string[] args)
{
var testData = new List<ItemWithDetails>()
{
new ItemWithDetails("Small"),
new ItemWithDetails("Small"),
new ItemWithDetails("Medium"),
new ItemWithDetails("Medium"),
new ItemWithDetails("Medium"),
new ItemWithDetails("Large"),
new ItemWithDetails("Large"),
new ItemWithDetails("Large"),
};
// Trying to get the average of each detail, per size.
var detailSummed = from item in testData
select new
{
size = item.Size,
detailsSummed = from detail in item.Details
group detail by detail.Key into detailGroup
select new
{
detailName = detailGroup.Key,
detailSum = detailGroup.Sum(a => (a.Value))
}
};
var averageAcrossItems = from item in detailSummed
group item by item.size into itemGroup
select new
{
size = itemGroup.Key,
detailsAveraged = // not sure how I can average across items, while at this level. Do I have to flatten it?
}
}
}
}
更新:
使用 Adam Mills 代码,我更接近了,结合了两个独立的 LINQ 查询。可以将其制成一个希望更具可读性的 LINQ 查询吗?
var detailSummed = from item in testData
select new
{
size = item.Size,
detailsSummed = from detail in item.Details
group detail by detail.Key into detailGroup
select new
{
detailName = detailGroup.Key,
detailSum = detailGroup.Sum(a => (a.Value))
}
};
var test2 = detailSummed.GroupBy(x => x.size)
.Select(y =>
new
{
Size = y.Key,
DetailAverages = y .SelectMany(x => x.detailsSummed)
.GroupBy(x => x.detailName)
.Select(x => new KeyValuePair<string, double>(x.Key, x.Average(c => c.detailSum)))
});