我的数据格式如下..
UserId Property1 Property2 Property3 Testval
1 1 1 10 35
2 1 2 3 45
3 2 5 6 55
and so on..
我有几个标准,下面是几个例子。
a) Where Property1=1 and Property3=10
b) Where Property1!=1 and Property2=5
我需要的是用户数和数量。那些属于这些标准的普通人,以及其他没有这些标准的人。
因此,结果数据结构如下..
User Count
Criteria Users
a 100
b 200
rest 1000
TestVal Average
Criteria avg
a 25
b 45
rest 15
我知道如何单独获取特定标准的用户列表。
data.Where(w=>w.Property1==1).Select(s=>s.UserId).ToList()
但是我如何获得usercount和avg val,更重要的是为其他用户提供相同的功能。
真心感谢任何帮助
由于
答案 0 :(得分:4)
您似乎正在寻找按标准分组。像这样:
var result = data.GroupBy(x =>
x.Property1 == 1 && x.Property3 == 10 ? 0 :
x.Property1 != 1 && x.Property2 == 5 ? 1 :
// ...
-1)
.Select(g => new
{
Criteria = g.Key,
Users = g.Count(),
Avg = g.Average(x => x.Testval),
})
.ToList();
答案 1 :(得分:2)
要获得特定标准的计数/平均值,这很容易
Func<MyUser, boolean> criterion1 = user => user.Property1==1;
var avg = data.Where(criterion1).Average(user => user.Testval);
var count = data.Where(criterion1).Count();
(这将枚举数据两次,所以如果这是一个问题,你可以在计算之前实现数据)
如果你想评估多个标准(并且不想像标准那样多次重复这段代码),你可以将它们放在字典中,并循环遍历它们:
var criteria = new Dictionary<string, Func<MyUser, boolean>>{
{ "criterion1", user => user.Property1==1 },
{ "criterion2", user => user.Property1!=1 && user.Property2=5 },
//...
}
foreach (var criterion in criteria){
var avg = data.Where(criterion.Value).Average(user => user.Testval);
var count = data.Where(criterion).Count();
Console.WriteLine($"{criterion.Key} average: {avg}, count: {count}");
}
您还可以将结果放在另一个字典中,例如
var results = new Dictionary<string, Tuple<string, string>>();
foreach (var criterion in criteria){
var avg = data.Where(criterion.Value).Average(user => user.Testval);
var count = data.Where(criterion).Count();
results.Add(criterion.Key, Tuple.Create(avg, count));
}
然后制作更好看的报告,或者您甚至可以创建一个更容易打印的特定结果类。
要获得其余的(不符合任何谓词的数据的计数/平均值),您可以循环遍历所有谓词,否定它们;
var query = data;
foreach (var criterion in criteria.Values){
query = query.Where(user => !criterion(user));
}
var restAvg = query.Average(user => user.Testval);
var count = query.Count();
答案 2 :(得分:2)
您可以使用select new来返回包含您的条件的新的匿名类型对象。
public void Test()
{
var list = new List<User>();
list.Add(new User {UserId = 1, Property1 = 1, Property2 = 1, Property3 = 10, Testval = 35});
list.Add(new User {UserId = 1, Property1 = 2, Property2 = 2, Property3 = 3, Testval = 45});
list.Add(new User {UserId = 1, Property1 = 5, Property2 = 5, Property3 = 6, Testval = 55});
Func<User, bool> crit = u => u.Property1 == 1 & u.Property3==10;
var zz = list.Where(crit)
.GroupBy(t => new {ID = t.UserId})
.Select(w => new
{
average = w.Average(a => a.Testval),
count = w.Count(),
rest = list.Except(list.Where(crit)).Average(a => a.Testval)
}).Single();
}