注册 登录
编程论坛 C# 论坛

【求助】筛选数据

venomlk 发布于 2021-09-13 18:36, 1814 次点击
有一个list<自定义结构>,结构中包括“年级、班级、姓名、语文成绩、数学成绩、物理成绩、化学成绩、历史成绩、体育成绩,总分”
想实现的是:最好利用linq一次性筛选出各年级、各班级中总分前十名的明细,并且明细以年级、班级、总分降序排序(各科成绩的字段也需要保留,换句话说就是,在list中的明细以年级、班级、总分进行排序,把各年级、班级前十的数据留下,其它删掉)
大概语句类似:list.groupby(l...........).take(10)

谢谢各位老师!
4 回复
#2
qq28895779662021-09-14 13:55
把全部人按规则个排序,输出到列表,取不同年级和班级的前几个,那个Group忘了,就用循环判断了
应该是
var Result_List = Infos.OrderByDescending(r => r.Result_Total).OrderBy(c => c.Classes_Id).OrderBy(g => g.Grade_Id).ToList().GroupBy(。。。。。什么的)


程序代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace Test_2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        public class Info
        {
            public int Grade_Id; // 年级Id值
            public int Classes_Id; // 班级Id值
            public string Grade; // 年级名称
            public string Classes; // 班级名称
            public string Name; // 姓名
            public double Result_1; // 成绩1
            public double Result_2; // 成绩2
            public double Result_Total; // 总成绩
            public Info(int g_id, int c_id, string g, string c, string n, double r1, double r2)
            {
                Grade_Id = g_id;
                Classes_Id = c_id;
                Grade = g;
                Classes = c;

                Name = n;
                Result_1 = r1;
                Result_2 = r2;
                Result_Total = r1 + r2;
            }
        }
        public static List<Info> Infos = new List<Info>();


        private void button1_Click(object sender, EventArgs e)
        {
            Infos.Add(new Info(0, 0, "一年级", "一班", "AA", 10.0, 10.0));
            Infos.Add(new Info(0, 0, "一年级", "一班", "BB", 9.0, 9.0));
            Infos.Add(new Info(0, 0, "一年级", "一班", "CC", 8.0, 8.0));
            Infos.Add(new Info(0, 1, "一年级", "二班", "EE", 6.0, 6.0));
            Infos.Add(new Info(0, 1, "一年级", "二班", "FF", 5.0, 6.0));
            Infos.Add(new Info(0, 1, "一年级", "二班", "DD", 11.0, 11.0));

            Infos.Add(new Info(1, 1, "二年级", "二班", "QQ", 5.0, 5.0));
            Infos.Add(new Info(1, 1, "二年级", "二班", "PP", 7.0, 7.0));
            Infos.Add(new Info(1, 1, "二年级", "二班", "RR", 6.0, 6.0));
            Infos.Add(new Info(1, 0, "二年级", "一班", "KK", 10.0, 10.0));
            Infos.Add(new Info(1, 0, "二年级", "一班", "MM", 9.0, 9.0));
            Infos.Add(new Info(1, 0, "二年级", "一班", "OO", 8.0, 8.0));


            // 全部人先按照年级、班级、总分排序
            var Result_List = Infos.OrderByDescending(r => r.Result_Total).OrderBy(c => c.Classes_Id).OrderBy(g => g.Grade_Id).ToList();
            // 全部排序出来了,按顺序取不同年级和班级的前几个就可以了,写个循环判断就可以了
            for (int i = 0; i < Result_List.Count; i++)
            {
                richTextBox1.AppendText("年级:" + Result_List[i].Grade + "  班级:" + Result_List[i].Classes + "  姓名:" + Result_List[i].Name + "  成绩1:" + Result_List[i].Result_1 + "  成绩2:" + Result_List[i].Result_2 + "  总分:" + Result_List[i].Result_Total + "\r");
            }

        }
    }
}

#3
venomlk2021-09-15 08:52
多谢qq2889577966版主的回复!
程序中其它的条件筛选都是用linq实现的,只差这一个,所以也想用linq来实现(可能有点儿强迫症),呵呵
再次多谢qq2889577966版主的关注!
#4
qq28895779662021-09-15 11:58
只能取每个年级和班级的第一名只能用First(),取10个咋取呢??有知道的说下

var Result_List = Infos.OrderByDescending(r => r.Result_Total).OrderBy(c => c.Classes_Id).OrderBy(g => g.Grade_Id).GroupBy(p => new { p.Grade, p.Classes }).Select(x => x.First()).ToList();


[此贴子已经被作者于2021-9-15 12:03编辑过]

#5
venomlk2023-07-07 17:01
回复一下较早之前自己发的求助帖。。感觉还挺有意思
ilist.OrderByDescending(xs => xs.年级).ThenByDescending(xs => xs.班级).ThenByDescending(xs => xs.总分).GroupBy(xs => new { xs.年级, xs.班级 }).SelectMany(xs => xs.Take(10)).ToList();
1