-1

I have a in-memory List of Job objects, were the Job object has a propery called Salary.

How do I use LINQ or C# to filter this list to only contain the list of jobs with salaries in the top 10 or bottom 10 percentile?

Here is my attempt, which seems to work for me so far:

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();
Abe
  • 5,806
  • 11
  • 44
  • 74
  • This will get you part of the way there: http://stackoverflow.com/questions/4872946/linq-query-to-select-top-5 – Robert Harvey Apr 08 '13 at 19:05
  • You really need to study LINQ. This is a fairly elementary question. What have you tried so far? – tier1 Apr 08 '13 at 19:07
  • 3
    In fairness, he *may* be stuck on calculating the range of the percentile, which is more arithmetic in nature. @Abe : Do you know how to order something using Linq? If not, then what tkcsam said applies. – Matthew Watson Apr 08 '13 at 19:24
  • @MatthewWatson: He should probably put what he's tried so far, then. – Colin DeClue Apr 08 '13 at 20:10
  • Thanks for the support. Yes, I understand the basics of LINQ, but I was trying to figure out the statistical formula using LINQ. Anyway, please see my answer for my attempt at top 10 percentile and bottom 10 percentile.. – Abe Apr 09 '13 at 03:34

2 Answers2

9

First, you'll want to calculate how many entries constitute 10%. You can do this by dividing the size of the list by 10 (and rounding or truncating to get an integer). Let's call this number X.

Next, you'll want to order the list by salaray in descending order. You'll want to take the first X elements in the list. These will be the ones in the top 10%.

To get the bottom 10%, you'll want to skip the first 90% (you can use 9X or subtract X from the full size - one of those might not work as expected) before taking X from the list. Alternately, you could order the list by salary and take the first X.

It would also help to use the System.Linq namespace.

yoozer8
  • 6,966
  • 6
  • 47
  • 84
1

I've built an Extension for removing percentage of a list. all you need to do is order the list before using the extension.

   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>);
    }
Martea
  • 497
  • 1
  • 5
  • 18