送大分!根据抢得 的钱数,同时取出一个list的前10%和前30%(人数),LINQ,只要回复就给分

秋的红果实 2019-02-18 10:28:02
快1年没来了,看了下,多数还是老熟人

问题应该不难,类似抢红包,将钱发给多个部门,当然每个部门有数量不等的人,供他们抢,现在已经将抢得的结果放到list
每个list元素结构类似下面

class info
{
public int ID; //职工ID
public float money;
public string department;

}



要求:
统计出抢得钱数排在前10%和30%的人数中,各个部门的人数。哈,就是group by,orderby。
关键是,要同时取出来,如下面样子
抢钱详情表如下
ID 抢得钱数 所属部门
1 100 部门1
2 80 部门3
3 70 部门3
4 50 部门2
5 40 部门3
6 30 部门1
7 20 部门2
8 10 部门3
9 5 部门1
10 3 部门3

结果表:
部门 前10%的人数 前30%的人数
部门1 1 1
部门2 0 0
部门3 0 2

解释:根据“详情表”,前10%的只有一个(100元),并属于部门1;前30%的共有三个(100,80,70),一个属于部门1,另两个属于部门3,于是有了“结果表”

只要回复就给分

...全文
1259 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
秋的红果实 2019-03-01
  • 打赏
  • 举报
回复
感谢大家 出于执行效率和可维护原因,最终使用了基本算法 结帖散分
  • 打赏
  • 举报
回复

var list = new List<info>
{
new info{ID= 1,money= 100,department="部门1"},
new info{ID= 2,money= 100,department="部门3"},
new info{ID= 3,money= 80,department="部门3"},
new info{ID= 4,money= 80,department="部门2"},
new info{ID= 5,money= 80,department="部门3"},
new info{ID= 6,money= 80,department="部门1"},
new info{ID= 7,money= 80,department="部门2"},
new info{ID= 8,money= 80,department="部门3"},
new info{ID= 9,money= 80,department="部门1"},
new info{ID= 10,money= 80,department="部门3"},
};

var moneys = list.GroupBy(x => x.money).OrderByDescending(x => x.Key).Select(x => x.Key).Take(3).ToList();

while(moneys.Count < 3)
moneys.Add(0);

var query = (from depart in list.Select(x=>x.department).Distinct() select new
{
部门 = depart,
前百分之十的人数 = list.Where(x=>x.department == depart && x.money >= moneys[0]).Count(),
前百分之三十的人数 = list.Where(x => x.department == depart && x.money >= moneys[2]).Count()
}).ToList();

秋的红果实 2019-02-24
  • 打赏
  • 举报
回复
更正: #14说得还不对,是末尾有并列 是这种情况,举例: ID 抢得钱数 所属部门 1 100 部门1 2 80 部门3 3 70 部门2 4 70 部门3 5 50 部门2 6 40 部门3 7 30 部门1 8 20 部门2 9 10 部门3 10 5 部门1 末尾有并列! 现在正在取舍,抽样测试,选择执行效率最高的方案
秋的红果实 2019-02-24
  • 打赏
  • 举报
回复
真是辛苦大家了! 有个棘手的问题,忘了说了,不好意思,就是抢到的钱数一样,有并列的,如下 ID 抢得钱数 所属部门 1 100 部门1 2 80 部门3 3 80 部门2 4 70 部门3 5 50 部门2 6 40 部门3 7 30 部门1 8 20 部门2 9 10 部门3 10 5 部门1 有两个80,这样前30%就是四个了(100,80,80,70),而不是三个了,take(3)就不行了,还可能是五个(100,80,80,80,70)
秋的红果实 2019-02-24
  • 打赏
  • 举报
回复
@刘才鬼,3# 你的写法,输出结果是: 部门 前10%的人数 前30%的人数 部门1 0 1 部门2 0 0 部门3 1 2 不是预期,你再改改
GAMER丶 2019-02-21
  • 打赏
  • 举报
回复
射手座cl 2019-02-20
  • 打赏
  • 举报
回复
新手用dt和for循环做的
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.jisuan();
}
public void jisuan()
{
DataTable dt = new DataTable();
dt.Columns.Add("ID",typeof(int));
dt.Columns.Add("money", typeof(double));
dt.Columns.Add("department", typeof(string));
dt.Rows.Add(1,"100","部门1");
dt.Rows.Add(2, "80", "部门3");
dt.Rows.Add(3, "70", "部门3");
dt.Rows.Add(4, "50", "部门2");
dt.Rows.Add(5, "40", "部门3");
dt.Rows.Add(6, "30", "部门1");
dt.Rows.Add(7, "20", "部门2");
dt.Rows.Add(8, "10", "部门3");
dt.Rows.Add(9, "5", "部门1");
dt.Rows.Add(10, "3", "部门3");
dt.DefaultView.Sort = "money desc";
dt = dt.DefaultView.ToTable();
int bm1 = 0,bm11=0;
int bm2 = 0,bm22=0;
int bm3 = 0,bm33=0;
DataTable dt2 = new DataTable();
dt2.Columns.Add("部门",typeof(string));
dt2.Columns.Add("前0.1", typeof(int));
dt2.Columns.Add("前0.3", typeof(int));
for(int i=0;i<dt.Rows.Count*0.1;i++)
{
if (dt.Rows[i]["department"] == "部门1")
{
bm1++;
}
if (dt.Rows[i]["department"] == "部门2")
{
bm2++;
}
if (dt.Rows[i]["department"] == "部门3")
{
bm3++;
}
}
for (int i = 0; i < dt.Rows.Count * 0.3; i++)
{
if (dt.Rows[i]["department"] == "部门1")
{
bm11++;
}
if (dt.Rows[i]["department"] == "部门2")
{
bm22++;
}
if (dt.Rows[i]["department"] == "部门3")
{
bm33++;
}
}
dt2.Rows.Add("部门1",bm1,bm11);
dt2.Rows.Add("部门2", bm2, bm22);
dt2.Rows.Add("部门3", bm3, bm33);
}
}

OrdinaryCoder 2019-02-19
  • 打赏
  • 举报
回复
感觉数据量小,逻辑简单的时候for循环理解起来比LINQ要好,不知道是不是因为我是linq新手的原因。
小黑哥gs 2019-02-19
  • 打赏
  • 举报
回复
for循环吧,非LINQ么
  • 打赏
  • 举报
回复
表示没看明白题目,看答案看明白了…………
  • 打赏
  • 举报
回复
            var list = new List<info>
            {
                new info{ID= 1,money= 100,department="部门1"},
new info{ID= 2,money= 80,department="部门3"},
new info{ID= 3,money= 70,department="部门3"},
new info{ID= 4,money= 50,department="部门2"},
new info{ID= 5,money= 40,department="部门3"},
new info{ID= 6,money= 30,department="部门1"},
new info{ID= 7,money= 20,department="部门2"},
new info{ID= 8,money= 10,department="部门3"},
new info{ID= 9,money= 5,department="部门1"},
new info{ID= 10,money= 3,department="部门3"},
            };

            var query = from dp in list.Select(x => x.department).Distinct()
                        join _10 in list.Take(1).GroupBy(x => x.department)
                        .Select(g => new
                        {
                            department = g.Key,
                            Count = g.Count()
                        }) on dp equals _10.department into _10T
                        from t_10 in _10T.DefaultIfEmpty()
                        join _30 in list.Take(3).GroupBy(x => x.department)
                        .Select(g => new
                        {
                            department = g.Key,
                            Count = g.Count()
                        }) on dp equals _30.department into _30T
                        from t_30 in _30T.DefaultIfEmpty()
                        select new
                        {
                            department = dp,
                            T_10 = t_10?.Count??0,
                            T_30 = t_30?.Count??0
                        };
            foreach (var tmp in query)
            {
                Console.WriteLine("{0} {1} {2}", tmp.department, tmp.T_10, tmp.T_30);
            }
  • 打赏
  • 举报
回复
分别group后再join起来
圣殿骑士18 2019-02-18
  • 打赏
  • 举报
回复
其实这种问题用linq太啰嗦了。还不如直接for循环更简洁。

==========
欢迎关注微信公众号 “产品技术知与行” ,打造全面的结构化知识库,包括原创文章、免费课程(C#,Java,Js)、技术专题、视野知识、源码下载等内容。
最新文章:多种Timer的场景应用 https://mp.weixin.qq.com/s/TJKi7PBj3nznf9FClirXUA
liusa1997 2019-02-18
  • 打赏
  • 举报
回复
var result = (from rs in list.Select(x => x.Name).Distinct()
select new
{
Department = rs ,
Count10Percent = list.Take(1).Join(list.Select(x => x.Name).Distinct(), x => x.Name, y => y, (x, y) => new { Name = x.Name, Age = x.Age }).Where(x=>x.Name==rs ).Count(),
Count30Percent = list.Take(3).Join(list.Select(x => x.Name).Distinct(), x => x.Name, y => y, (x, y) => new { Name = x.Name, Age = x.Age }).Where(x => x.Name == rs ).Count(),
})
.ToList();
正怒月神 2019-02-18
  • 打赏
  • 举报
回复
感觉子查询就可以了。
正怒月神 2019-02-18
  • 打赏
  • 举报
回复
static List<User> list = new List<User>()
        {
            new User(){ID=1, Name="部门1",Age=100},
            new User(){ID=2,Name="部门3",Age=80},
            new User(){ID=3,Name="部门3",Age=70},
            new User(){ID=4,Name="部门2",Age=50},
            new User(){ID=5,Name="部门3",Age=40},
            new User(){ID=6,Name="部门1",Age=30},
            new User(){ID=7,Name="部门2",Age=20},
            new User(){ID=8,Name="部门3",Age=10},
            new User(){ID=9,Name="部门1",Age=5},
            new User(){ID=10,Name="部门3",Age=3},
        };

        
        static void Main(string[] args)
        {

            var q = (from b in list.Select(x => x.Name).Distinct()
                     select new
                     {
                         Department = b,
                         Count1 = list.Take(1).Join(list.Select(x => x.Name).Distinct(), x => x.Name, y => y, (x, y) => new { Name = x.Name, Age = x.Age }).Where(x=>x.Name==b).Count(),
                         Count2 = list.Take(3).Join(list.Select(x => x.Name).Distinct(), x => x.Name, y => y, (x, y) => new { Name = x.Name, Age = x.Age }).Where(x => x.Name == b).Count(),
                     })
                     .ToList();
                
            



            Console.ReadLine();
        }
极客诗人 2019-02-18
  • 打赏
  • 举报
回复
借#2的数据

var list = new List<info>
{
new info{ID= 1,money= 100,department="部门1"},
new info{ID= 2,money= 80,department="部门3"},
new info{ID= 3,money= 70,department="部门3"},
new info{ID= 4,money= 50,department="部门2"},
new info{ID= 5,money= 40,department="部门3"},
new info{ID= 6,money= 30,department="部门1"},
new info{ID= 7,money= 20,department="部门2"},
new info{ID= 8,money= 10,department="部门3"},
new info{ID= 9,money= 5,department="部门1"},
new info{ID= 10,money= 3,department="部门3"},
};

var list1 = list.Select(x => x.department).Distinct().GroupJoin(list.OrderBy(m => m.money)
.Take(list.Count()/10)
.GroupBy(m => m.department)
.Select(x => new { department = x.Key, Count_10 = x.Count()}), T1 => T1, T2 => T2.department, (T1, T2) => new
{
department = T1,
Count_10 = T2.Sum(x=>x.Count_10)
})
.GroupJoin(list.OrderBy(m => m.money)
.Take(list.Count() / 10 * 3)
.GroupBy(m=>m.department)
.Select(x => new { department = x.Key, Count_30 = x?.Count()??0 }), T1 => T1.department, T2 => T2.department, (T1, T2) => new
{
depatment = T1.department,
Count_10 = T1.Count_10,
Count_30 = T2.Sum(x => x.Count_30)
}).ToList()

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧