按结果工资排名前10位的百分位数

时间:2013-04-08 19:04:09

标签: c# linq linq-to-objects percentile

我有一个内存的Job对象列表,Job对象有一个名为Salary的属性。

如何使用LINQ或C#过滤此列表,仅包含前10名或后10名工资的工作列表?

这是我的尝试,到目前为止似乎对我有用:

var tenthPercentileCount = allJobsCount / 10;
var top10PercentileJobs = allJobs
    .OrderByDescending(j => j.Salary.SalaryAmount)
    .Take(tenthPercentileCount)
    .ToList();
var bottom10PercentileJobs = allJobs
    .OrderBy(j => j.Salary.SalaryAmount)
    .Take(tenthPercentileCount)
    .ToList();

2 个答案:

答案 0 :(得分:8)

首先,您需要计算10%的条目数。您可以通过将列表的大小除以10(并舍入或截断以获得整数)来完成此操作。我们把这个号码称为X。

接下来,您需要以降序顺序订购列表 salaray。您需要获取列表中的前X个元素。这些将是前10%的。

要获得最低10%,您需要跳过前90%(您可以使用9X或从完整尺寸中减去X - 其中一个可能无法按预期工作) 从列表中选择 X.或者,您可以订购列表工资,获取第一个X.

使用System.Linq命名空间也很有帮助。

答案 1 :(得分:0)

我已经构建了一个用于删除列表百分比的扩展。您需要做的就是在使用扩展程序之前订购列表。

   public static IEnumerable<T> RemoveBeforeAndAfter<T>(this IEnumerable<T> source, int percent, bool removeLast = false, bool removeFirst = false)
    {
        var enumerable = source as IList<T> ?? source.ToList();
        var sourceCount = enumerable.Count();
        var noRemove = Convert.ToInt32(Math.Ceiling((percent / 100D) * sourceCount));
        var remove = new List<T>();
        if (enumerable.Any())
        {
            if (removeLast)
                remove.AddRange(enumerable.Reverse().Take(noRemove));
            if (removeFirst)
                remove.AddRange(enumerable.Take(noRemove));
            return enumerable.Where(x => remove.Any(r => x.Equals(r))).ToList();

        }

        return default(IEnumerable<T>);
    }