首页 新闻 会员 周边

linq 统计并排名

0
悬赏园豆:200 [已解决问题] 解决于 2013-11-01 14:01
 
已知:
一个等级实体
public class Levels
{
    public string ID { get; set; } //编号
    public string Name { get; set; } //名称
public int No {get;set;}//排名
} List<Levels> li = new List<Levels>(); li.Add(new Levels { ID = "A", Name = "一般" }); li.Add(new Levels { ID = "B", Name = "严重" }); li.Add(new Levels { ID = "C", Name = "紧急" });
li.Add(new Levels { ID = "D", Name = "危急" }); 一个数据实体
public class Data { public string DID { get; set; }//编号 public string LID { get; set; }//等级编号(关联Levels中的ID) public int Num { get; set; }//次数 } List<Data> dli = new List<Data>(); dli.Add(new Data { DID = "1", LID = "A", Num = 5 });
dli.Add(new Data { DID = "2", LID = "B", Num = 3 });
dli.Add(new Data { DID = "3", LID = "C", Num = 3 });

问题:需要根据等级进行次数统计,然后排名(注:1.次数相同排名相同;2.没有出现的等级次数为0,最后也要出现排名)

        {linq语句}

结果:

         排名          等级        次数

          1            一般            5

          2            严重            3

          2            紧急            3

          3            危急            0

 

修改了一些需求内容,这样应该明白了吧

        

grn的主页 grn | 初学一级 | 园豆:22
提问于:2013-11-01 11:44
< >
分享
最佳答案
0
     var levels = li;
        var datas =dli;
        var distinctDatas = datas.Select(n => n.Num).Distinct().OrderByDescending(n => n).ToList();
        var paiming = from c in levels
                      join d in datas on
                      c.ID equals d.LID
                      into temp
                      from tt in temp.DefaultIfEmpty()
                      let no = (tt == null ? distinctDatas.Count + 1 : distinctDatas.IndexOf(tt.Num) + 1)
                      let num = (tt == null ? 0: tt.Num)
                      select new { no, c.ID,num };
收获园豆:140
Yu | 专家六级 |园豆:12980 | 2013-11-01 13:26

膜拜一下,Good~!!

Zery | 园豆:6151 (大侠五级) | 2013-11-01 14:06
其他回答(4)
0

 

根据我目前掌握的知识,提供以下建议:

1、想要用一条LINQ语句实现需求,应该是比较难或者说不太可能的。

2、需求仍然不够明确,比如第2名相同的有2个,第3名要写第3还是第4?

3、我目前知道的,只能用代码,循环语句,当然,性能问题另外考虑。

4、如果想要一句LINQ实现,建议是否可以修改需求,比如相同次数,随机排名。就是有的第2名,有的第3名。

5、就你的问题而言,LEVELS类在这个问题里面没有任何用处。

    因为你要的结果是"A",而不是"一般"。所以就算有LINQ语句能够完成需求,也不需要LEVELS这个类。也就是说你提供了额外而无用的信息。

 

收获园豆:10
爱编程的大叔 | 园豆:30839 (高人七级) | 2013-11-01 11:59
0

如果想要实现得简单一点,最好把两个实体类中的一个实体类作为另一个实体类的属性。

毕竟他们之间是有关系的,所以还是建立关系。

收获园豆:10
悟行 | 园豆:12559 (专家六级) | 2013-11-01 12:33
0
            List<Levels> li = new List<Levels>();
            li.Add(new Levels { ID = "A", Name = "一般" });
            li.Add(new Levels { ID = "B", Name = "严重" });
            li.Add(new Levels { ID = "C", Name = "紧急" });
            List<Data> dli = new List<Data>();
            dli.Add(new Data { DID = "1", LID = "A", Num = 2 });
            dli.Add(new Data { DID = "2", LID = "B", Num = 2 });
            dli.Add(new Data { DID = "3", LID = "C", Num = 5 });
           

           var result = (from leve in li
                         join data in dli
                         on leve.ID equals data.LID
                         orderby data.Num descending 
                         select new
                                    {
                                        leve.ID,
                                        data.Num,
                                    } ).ToList();

            var ordery =result.ToArray();

            int count = 1;
            List<Result> oResults = new List<Result>();
            for (int i = 0; i < ordery.Length; i++)
            {
                //确定是否到数组边界
                if (i + 1 < ordery.Length)
                {
                    //如果与list中下一位的Num数相等则 排名Count数不变
                    if (ordery[i].Num == ordery[i + 1].Num)
                    {
                        var item = new Result {id = count, Name = ordery[i].ID, Num = ordery[i].Num};
                        oResults.Add(item);
                    }
                    else
                    {
                        //如果与list中下一位的Num数不相等则 排名Count加1
                        var item = new Result { id = count, Name = ordery[i].ID, Num = ordery[i].Num };
                        oResults.Add(item);
                        count++;
                    }
                }
                //如果是最后一位了就直接添加
                else
                {
                    var item = new Result { id = count, Name = ordery[i].ID, Num = ordery[i].Num };
                    oResults.Add(item);
                }
            }

            foreach (var i in oResults)
            {
                Console.WriteLine(i.id+"--"+i.Name+"--"+i.Num);
            }
            Console.Read();
        }
    }
    public class Levels
    {
        public string ID { get; set; } //编号
        public string Name { get; set; } //名称
        public int No { get; set; }//排名

    }
    public class Data
    {
        public string DID { get; set; }//编号
        public string LID { get; set; }//等级编号(关联Levels中的ID)
        public int Num { get; set; }//次数
    }

    public class Result
    {
        public int  id { get; set; } //排名Id
        public string Name { get; set; }//名称
        public int Num { get; set; }//次数
    }

 

中午闲着没事儿干,然后就写了写,主要是排名那有点麻烦,而且我觉得这种实现方法不科学...............先睡觉了.

收获园豆:30
Zery | 园豆:6151 (大侠五级) | 2013-11-01 12:45

你被楼主误导了。LEVELS类在这儿根本没有用处。

按照你的写法,给建议如下:

1、 var query = from c in dli
                       order by c.num
                       select c.lid, c.num

     这样就够了,多余还要去连接LEVELS类。

 

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2013-11-01 12:57
0
收获园豆:10
li-peng | 园豆:954 (小虾三级) | 2013-11-01 13:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册