r3plica r3plica - 11 days ago 6
C# Question

c# sort list by between two values asc or desc

Say I have a list of objects like this:

var products = new List<Product>();
products.Add(new Product { Name = "First", Price = 275.99 });
products.Add(new Product { Name = "Second", Price = 333.66 });
products.Add(new Product { Name = "Third", Price = 2455.99 });
products.Add(new Product { Name = "Forth", Price = 450.00 });


And I have a value like this:

var lower = 500;
var upper = 1000;
var direction = "Asc";


Now I wish to use
List<T>.Sort
to sort the products by items between the 2 values, using the direction to specify if it's ascending or descending.
Does anyone know how I can do this?




Update



I don't want to filter this list, I would like the matching products to be at the top of the list and the others to be at the bottom. If the direction is ascending I would epect:

Product { Name = "First", Price = 275.99 };
Product { Name = "Second", Price = 333.66 };
Product { Name = "Forth", Price = 450.00 };
Product { Name = "Third", Price = 2455.99 };


If I change the values to:

var lower = 300;
var upper = 1000;
var direction = "desc";


I would expect the output to be:

Product { Name = "Forth", Price = 450.00 };
Product { Name = "Second", Price = 333.66 };
Product { Name = "Third", Price = 2455.99 };
Product { Name = "First", Price = 275.99 };


I hope that makes sense

Answer

You can create a custom Comparer to achieve that:

var lower = 300;
var upper = 1000;
var direction = "Asc";

Func<Product, bool> isInRange = p => p.Price >= lower && p.Price <= upper;

var byPricesInRangeComparer = Comparer<Product>.Create((x, y) => {
    var ret = 0;
    var xInRange = isInRange(x);
    var yInRange = isInRange(y);

    if (xInRange && !yInRange)
        ret = -1;
    else if (yInRange && !xInRange)
        ret = 1;
    else
        ret = x.Price >= y.Price ? -1 : 1;

    return direction == "Asc" ? ret : (0 - ret);
});

products.Sort(byPricesInRangeComparer);

(Judging by the desired outputs you posted, you also want to compare by the actual price in case both prices falls within the expected range)

See MSDN