Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorter way to order a list by boolean functions

I have a list that needs to be ordered in a specific way. I've currently solved it like this:

var files = GetFiles()
  .OrderByDescending(x => x.Filename.StartsWith("ProjectDescription_"))
  .ThenByDescending(x => x.Filename.StartsWith("Budget_"))
  .ThenByDescending(x => x.Filename.StartsWith("CV_"))
  .ToArray();

The files are going to be merged into a single PDF file and the point here is that certain files should come at the beginning, and the rest at the end.

I'm wondering if there is a better way to write this "pattern", cause it feels rather blah and would become even more blah if there were more cases.


Things I'd like to avoid, but not sure how: Multiple passes through the list, more StartsWith calls per file than necessary, more code than necessary, etc.

Basically I think I'd like an OrderByPredicates sort of thing which smartly fulfilled those criteria and whose API was used sort of like this:

var predicates = new Func<boolean, File>[] {
  x => x.Filename == "First"
  x => x.Filename.StartsWith("Foo_"),
  x => x.Filename.StartsWith("Bar_"),
};

var files = GetFiles()
  .OrderByPredicates(predicates)
  .ThenBy(x => x.Filename);
like image 596
Svish Avatar asked Mar 04 '15 13:03

Svish


1 Answers

Compact (except for a little helper method) and easy to extend:

private static readonly string[] Prefixes = {"ProjectDescription_", "Budget_", "CV_"};

public static int PrefixIndex(string name)
{
  for (int i = 0; i < Prefixes.Length; i++)
  {
    if (name.StartsWith(Prefixes[i]))
    {
      return i;
    }
  }
  return int.MaxValue;
}

// ...

var files = GetFiles().OrderBy(x => PrefixIndex(x.Name));
like image 102
Sebastian Negraszus Avatar answered Sep 21 '22 11:09

Sebastian Negraszus