转换一个实体对象-列到行并重新组合-C#Linq
本文关键字:新组合 组合 -C#Linq -列 一个 实体 转换 对象 | 更新日期: 2023-09-27 18:27:13
我得到一个实体对象,如下所示:
{qid=1110, cid=94, gid=3, sid=10, cs=6}
{qid=1110, cid=95, gid=3, sid=10, cs=4}
{qid=1110, cid=96, gid=3, sid=10, cs=6}
{qid=1110, cid=97, gid=3, sid=10, cs=0}
{qid=1111, cid=94, gid=3, sid=10, cs=5}
{qid=1111, cid=95, gid=3, sid=10, cs=5}
{qid=1111, cid=96, gid=3, sid=10, cs=5}
{qid=1111, cid=97, gid=3, sid=10, cs=5}
{qid=1110, cid=94, gid=4, sid=10, cs=6}
{qid=1110, cid=95, gid=4, sid=10, cs=4}
{qid=1110, cid=96, gid=4, sid=10, cs=6}
{qid=1110, cid=97, gid=4, sid=10, cs=4}
但我需要显示或转换如下:
qid || cid1cs || cid2cs || cid3cs || cid4cs || avg_cs || gid || sid
----------------------------------------------------------------------
1110|| 6 || 4 || 6 || 0 || 4 || 3 || 10
----------------------------------------------------------------------
1110|| 6 || 4 || 6 || 4 || 5 || 4 || 10
----------------------------------------------------------------------
1111|| 5 || 5 || 5 || 5 || 5 || 3 || 10
----------------------------------------------------------------------
其中cid1cs是cid=94的cs,cid2cs=95的cs,依此类推。。avg_cs是所有4个cs(cid1cs、cid2cs..)的平均值,需要对gid、sid和qid执行分组和排序。
在LINQ中可以做到这一点吗?我正在使用C#
有人能帮忙吗?
提前感谢
我给你举了一个例子,但请记住,这非常容易出错!但它是有效的。当行数少于4行时,它将失败。
我认为GetHashCode()有一个更好的实现,但这会起作用。
public class Triplet : IEquatable<Triplet>
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; }
public override int GetHashCode()
{
return Value1.GetHashCode() + Value2.GetHashCode() + Value3.GetHashCode();
}
public bool Equals(Triplet other)
{
int d1 = this.Value1.CompareTo(other.Value1);
if (d1 != 0)
return false;
int d2 = this.Value2.CompareTo(other.Value2);
if (d2 != 0)
return false;
int d3 = this.Value3.CompareTo(other.Value3);
if (d3 != 0)
return false;
return true;
}
}
这个linq代码:
var data = new[]
{
new {qid=1110, cid=94, gid=3, sid=10, cs=6},
new {qid=1110, cid=95, gid=3, sid=10, cs=4},
new {qid=1110, cid=96, gid=3, sid=10, cs=6},
new {qid=1110, cid=97, gid=3, sid=10, cs=0},
new {qid=1111, cid=94, gid=3, sid=10, cs=5},
new {qid=1111, cid=95, gid=3, sid=10, cs=5},
new {qid=1111, cid=96, gid=3, sid=10, cs=5},
new {qid=1111, cid=97, gid=3, sid=10, cs=5},
new {qid=1110, cid=94, gid=4, sid=10, cs=6},
new {qid=1110, cid=95, gid=4, sid=10, cs=4},
new {qid=1110, cid=96, gid=4, sid=10, cs=6},
new {qid=1110, cid=97, gid=4, sid=10, cs=4}
};
var avg = from item in data
group item by new Triplet { Value1 = item.qid, Value2 = item.gid, Value3 = item.sid } into groupedItems
select new
{
qid = groupedItems.Key,
cid1cs = groupedItems.First().cs,
cid2cs = groupedItems.Skip(1).First().cs,
cid3cs = groupedItems.Skip(2).First().cs,
cid4cs = groupedItems.Skip(3).First().cs,
avg_cs = groupedItems.Average(i => i.cs),
gid = groupedItems.First().gid,
sid = groupedItems.First().sid
};
首先,LINQPad是你的朋友,下载它,使用它,你会喜欢它的。它包含许多示例,并教你更多关于LINQ的知识。
关于您的分组/交叉表问题:
var data = new[]
{
new {qid=1110, cid=94, gid=3, sid=10, cs=6},
new {qid=1110, cid=95, gid=3, sid=10, cs=4},
new {qid=1110, cid=96, gid=3, sid=10, cs=6},
new {qid=1110, cid=97, gid=3, sid=10, cs=0},
new {qid=1111, cid=94, gid=3, sid=10, cs=5},
new {qid=1111, cid=95, gid=3, sid=10, cs=5},
new {qid=1111, cid=96, gid=3, sid=10, cs=5},
new {qid=1111, cid=97, gid=3, sid=10, cs=5},
new {qid=1110, cid=94, gid=4, sid=10, cs=6},
new {qid=1110, cid=95, gid=4, sid=10, cs=4},
new {qid=1110, cid=96, gid=4, sid=10, cs=6},
new {qid=1110, cid=97, gid=4, sid=10, cs=4}
};
var query = from item in data
group item by new { qid = item.qid, gid = item.gid, sid = item.sid } into grouped
select new
{
qid = grouped.Key.qid,
cid1cs = grouped.Where(item => item.cid == 94).Sum(item => item.cs),
cid2cs = grouped.Where(item => item.cid == 95).Sum(item => item.cs),
cid3cs = grouped.Where(item => item.cid == 96).Sum(item => item.cs),
cid4cs = grouped.Where(item => item.cid == 97).Sum(item => item.cs),
avg_cs = grouped.Average(item => item.cs),
gid = grouped.Key.gid,
sid = grouped.Key.sid
};
query.Dump();
最后一行是如何在LINQPad中输出结果,这样您就可以看到您所要求的结果。
您可以使用自定义相等比较器,下面是一个示例:
class Program
{
public class MyClass
{
public int qid { get; set; }
public int cid { get; set; }
public int gid { get; set; }
public int sid { get; set; }
public int cs { get; set; }
}
public class MyClassComaparer : IEqualityComparer<MyClass>
{
public bool Equals(MyClass x, MyClass y)
{
return x.qid == y.qid && x.gid == y.gid && x.sid == y.sid;
}
public int GetHashCode(MyClass obj)
{
return obj.qid;
}
}
static void Main(string[] args)
{
var list = new List<MyClass>();
list.Add(new MyClass() { qid = 1110, cid = 94, gid = 3, sid = 10, cs = 6 });
list.Add(new MyClass() { qid = 1110, cid = 95, gid = 3, sid = 10, cs = 4 });
list.Add(new MyClass() { qid = 1110, cid = 96, gid = 3, sid = 10, cs = 6 });
list.Add(new MyClass() { qid = 1110, cid = 97, gid = 3, sid = 10, cs = 0 });
list.Add(new MyClass() { qid = 1111, cid = 94, gid = 3, sid = 10, cs = 5 });
list.Add(new MyClass() { qid = 1111, cid = 95, gid = 3, sid = 10, cs = 5 });
list.Add(new MyClass() { qid = 1111, cid = 96, gid = 3, sid = 10, cs = 5 });
list.Add(new MyClass() { qid = 1111, cid = 97, gid = 3, sid = 10, cs = 5 });
list.Add(new MyClass() { qid = 1110, cid = 94, gid = 4, sid = 10, cs = 6 });
list.Add(new MyClass() { qid = 1110, cid = 95, gid = 4, sid = 10, cs = 4 });
list.Add(new MyClass() { qid = 1110, cid = 96, gid = 4, sid = 10, cs = 6 });
list.Add(new MyClass() { qid = 1110, cid = 97, gid = 4, sid = 10, cs = 4 });
var result = list.GroupBy(w => w, new MyClassComaparer()).Select(w => new
{
qid = w.Key.qid,
cid1cs = w.Where(e => e.cid == 94).Sum(e => e.cs),
cid2cs = w.Where(e => e.cid == 95).Sum(e => e.cs),
cid3cs = w.Where(e => e.cid == 96).Sum(e => e.cs),
cid4cs = w.Where(e => e.cid == 97).Sum(e => e.cs),
avg_cs = w.Average(i => i.cs),
gid = w.Key.gid,
sid = w.Key.sid
}).ToList();
Console.ReadKey();
}
}