2

having some trouble with something very easy (i hope)

i am receiving an array for sorting. I've created a dictionary for the keyselector. But i am missing the last piece to fix then ThenBy instead or re-ordering them everytime.

public List<Vehicle> OrderBy(string[] sorting, List<Vehicle> vehicles)
{
    return Order(sorting, vehicles, SortingFiltersVehicle);
}

//this is a generic implementation
private List<T> Order<T>(string[] sorting, List<T> vehicles, IDictionary<string, Func<T, object>> filters)
{
    if (!sorting.HasAnyValue())
        return vehicles;

    foreach (var orderby in sorting)
    {
        var key = orderby.Split("-")[0];
        if (filters.ContainsKey(key.Trim()))
        {
            var direction = orderby.Contains("desc") ? OrderByDirection.Descending : OrderByDirection.Ascending;
            vehicles = vehicles.OrderBy(filters[key], direction).ToList(); <== here is the problem
        }
    }

    return vehicles;
}

private static readonly IDictionary<string, Func<Vehicle, object>> SortingFiltersVehicle = new Dictionary<string, Func<Vehicle, object>>
{
    { "price", v => v.DiscountedPrice },
    { "make", v => v.Make },
    { "model", v => v.Model },
    { "trimline", v => v.Trimline },
};
Roelant M
  • 1,521
  • 10
  • 19
  • Is that `OrderBy` a custom extension method? LINQ doesn't have a built-in `OrderByDirection`. Perhaps you could expand your code into a [mcve]? – Camilo Terevinto Aug 10 '18 at 11:17
  • what is`filters`? what is the custom `OrderBy` you have here that takes an `OrderByDirection`? – Marc Gravell Aug 10 '18 at 11:17
  • 1
    I wonder if it might be a better idea to start from [here](https://stackoverflow.com/a/233505/23354), and simply add the code to detect a `-` prefix and reverse the direction on individual sorts... – Marc Gravell Aug 10 '18 at 11:19
  • @MarcGravell `filters` is the `SortingFiltersVehicle` at the bottom – Camilo Terevinto Aug 10 '18 at 11:21

1 Answers1

2

Untested, but this looks like it should work:

private List<T> Order<T>(string[] sorting, List<T> vehicles,
    IDictionary<string, Func<T, object>> filters)
{
    if (!sorting.Any()) return vehicles;

    IOrderedEnumerable<T> sorted = null;
    foreach (var orderby in sorting)
    {
        var key = orderby.Split("-")[0];
        if (filters.ContainsKey(key.Trim()))
        {
            var desc = orderby.Contains("desc");
            var filter = filters[key];
            if (sorted == null) sorted = desc ? vehicles.OrderByDescending(filter) : vehicles.OrderBy(filter);
            else sorted = desc ? sorted.ThenByDescending(filter) : sorted.ThenBy(filter);
        }
    }

    return sorted?.ToList() ?? vehicles;
}
Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • perfect! you only forgot to assign the sorted the firsttime, but that was a easy one ;) thnx! – Roelant M Aug 10 '18 at 12:06
  • @RoelantM where did I? that's what `if (sorted == null) sorted = desc ? vehicles.OrderByDescending(filter) : vehicles.OrderBy(filter);` does, no? – Marc Gravell Aug 10 '18 at 12:11