0

我得到一个实体对象如下:

{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= cs 95 等等.. avg_cs 是所有 4 个 cs (cid1cs, cid2cs..) 的平均数,并且需要对 gid、sid 和 qid 执行分组和排序.

是否可以在 LINQ 中做到这一点?我正在使用 C#

有人可以帮忙吗?

提前致谢

4

3 回答 3

1

我为您提供了一个示例,但请记住,这很容易出错!但它有效。当行数少于 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
                  };
于 2013-08-12T08:27:21.073 回答
0

首先,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 中输出结果,这样您就可以看到结果就是您所要求的。

于 2013-08-12T09:04:42.820 回答
0

您可以使用自定义相等比较器,这是一个示例:

  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();
    }   
  }
于 2013-08-12T09:04:58.407 回答