c#在两个值asc或desc之间排序列表

时间:2016-11-28 12:30:42

标签: c# sorting

说我有这样的对象列表:

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 });

我有这样的价值:

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

现在我希望使用List<T>.Sort按照2个值之间的项目对产品进行排序,使用方向指定它是升序还是降序。 有谁知道我怎么能这样做?

更新

我不想过滤此列表,我希望匹配的产品位于列表顶部,其他产品位于底部。如果方向上升,我会看到:

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

如果我将值更改为:

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

我希望输出为:

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

我希望这是有道理的

4 个答案:

答案 0 :(得分:4)

您可以创建自定义Comparer来实现:

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);

(根据您发布的所需产出判断,您还希望按实际价格进行比较,以防两种价格都落在预期范围内)

请参阅MSDN

答案 1 :(得分:2)

所以你想要所有数据,但如果两个项目都在 String imgCount = postObject.getString("images_count"); String is_encourage_user = postObject.getString("is_encourage_user"); 范围内,那么它们应该是[lower..upper]顺序;所有没有范围的值应该以任意顺序位于列表的末尾:

direction

答案 2 :(得分:1)

字符串不是很直观,但是

        Dictionary<string, Comparison<Product>> comparer = new Dictionary<string, Comparison<Product>>
        {
            ["asc"] = (a, b) => a.Price.CompareTo(b.Price),
            ["desc"] = (a, b) => b.Price.CompareTo(a.Price)
        };

        var lower = 500;
        var upper = 1000;
        var direction = "Asc";
        var trimmed = products.Where(p => p.Price >= lower && p.Price <= upper).ToList();
        trimmed.Sort(comparer[direction.ToLower()]);

[这是C#6,顺便说一句。]

修改

一种(低效)方式是过滤,对过滤器进行排序,创建一个新列表;

var trimmed = products.Where(p => p.Price >= lower && p.Price <= upper).ToList();
var excluded = products.Except(trimmed);
trimmed.Sort(comparer[direction.ToLower()]);
products = new List<Product>(trimmed);
products.AddRange(excluded);

答案 3 :(得分:0)

var result = products.Where(x => x.Price >= lower && x.Price <= upper);

if(direction.ToLower() == "asc")
    result = result.OrderBy(x=>x.Price);
else
    result = result.OrderByDescending(x=>x.Price);

如果你的下限是500而上限是1000,你应该在两者之间进行检查。