数字列表最低值在前,然后按输入日期

List of numbers lowest value first, and then by input date

所以我有一个来自数据库的价格列表。我想对其进行排序,以便列表中的第一个条目是编号最小的条目。然后所有其他条目都按输入日期排序。 如何做到这一点?

这是我的代码,有点乱,对不起,我正在尝试:)

            var itemPriceDate = itemPrice.OrderBy(d => d.Invoice.DateInvoice).ToList();
            var itemPriceDateLow= itemPriceDate.OrderBy(c => c.qtPrice).ThenBy(d => d.Invoice.DateInvoice);
            ViewBag.ItemPrice = itemPriceDateLow; ```

LINQ 工作的时候很棒,但有时它会做一些意想不到的事情。根据您的数据集有多大,您最好将其作为 returns 数据已排序的存储过程。

如果数据集很小或者您被迫使用 C# 来执行此操作,则可以选择使用自定义排序函数。在不知道数据的确切结构的情况下,这更像是一个笼统的例子,需要相应地进行调整。

假设您的列表存储在 itemPrice 变量中,如果您执行以下操作:

itemPrice.Sort((a, b) => {
                  int retVal = a.qtPrice < b.qtPrice;
                  return ret != 0 ? ret : a.Invoice.DateInvoice < b.Invoice.DateInvoice;
              });

将按 qtPrice 排序,然后回退到 DateInvoice 字段;您可能需要将小于号换成大于号才能获得您想要的订单。

一种就够了。我认为应该是:

var itemPriceDateLow= itemPriceDate.OrderBy(c => c.qtPrice).ThenBy(d => d.Invoice.DateInvoice);

这显然会给你整个 collection。如果你想获得最顶层的元素,你可能想使用 .First()。

要记住一件事 - 默认情况下,ThenBy、OrderBy 是升序的。

看看这个例子:

class Program
{

    static void Main(string[] args)
    {
        List<ItemPrice> items = new List<ItemPrice>();
        items.Add(new ItemPrice() { Date = DateTime.Now, QtyPrice = 1});
        items.Add(new ItemPrice() { Date = DateTime.Now.AddDays(-1), QtyPrice = 1});
        items.Add(new ItemPrice() { Date = DateTime.Now, QtyPrice = 2});

        var sortedItem = items.OrderBy(p => p.QtyPrice).ThenBy(p => p.Date).First();
        Console.WriteLine($"Default Ascending sort {sortedItem.Date}, {sortedItem.QtyPrice}");

        var sortedItemWithReverseDate = items.OrderBy(p => p.QtyPrice).ThenByDescending(p => p.Date).First();
        Console.WriteLine($"Descending sort on date {sortedItemWithReverseDate.Date}, {sortedItemWithReverseDate.QtyPrice}");
    }
}

class ItemPrice {
    public DateTime Date { get; set; }
    public decimal QtyPrice { get; set; }
}

它会给你:

默认升序排序 16/08/2021 12:47:34, 1 按日期 17/08/2021 12:47:34、1

降序排序

首先找出List(itemPrice)中的最低值。

double lowest_price = itemPrice.Min(c => c.qtPrice);

接下来,从列表中删除最低的元素。

var itemToRemove = itemPrice.Single(c => c.qtPrice == lowest_price);
itemPrice.Remove(itemToRemove);

接下来,根据输入的日期对剩余列表进行排序。

var newList = itemPrice.OrderByDescending(d => d.Invoice.DateInvoice).ToList();

最后,在第一个索引处添加最低元素

newList.Insert(0, lowest_price);

在这种情况下,您需要迭代集合两次,因为您首先需要知道聚合值(最小值)。然后,您可以使用自定义比较器,如下所示。

public class CustomComparer : IComparer<Item> 
{
    private int _minValue;
    public CustomComparer(int minValue)
    {
        _minValue= minValue;
    }

    public int Compare(Item instanceA, Item instanceB)
    {
        if(instanceA.Price == _minValue) return -1;
        if(instanceB.Price == _minValue) return 1;
        return instanceA.InputDate.CompareTo(instanceB.InputDate);
    }
}

现在您可以获取结果

var min = list.Min(x=>x.Price);
var result = list.OrderBy(x=>x,new CustomComparer(min));

示例,

public class Item
{
    public int Price{get;set;}
    public DateTime InputDate{get;set;}
}
var list = new List<Item>
{
        
        new Item{Price = 2,  InputDate=new DateTime(2021,3,1)},
        new Item{Price = 12, InputDate=new DateTime(2021,7,1)},
        new Item{Price = 12, InputDate=new DateTime(2021,9,1)},
        new Item{Price = 42, InputDate=new DateTime(2021,1,1)},
        new Item{Price = 32, InputDate=new DateTime(2021,6,1)},
        new Item{Price = 22, InputDate=new DateTime(2021,4,1)},
        new Item{Price = 2,  InputDate=new DateTime(2021,3,2)},
        new Item{Price = 12, InputDate=new DateTime(2021,2,1)}
};
    
var min = list.Min(x=>x.Price);
var result = list.OrderBy(x=>x,new CustomComparer(min));

输出

感谢您的所有意见。

对我来说正确的方法是。

按“降序(按日期)”排序我的“itemPrice”列表

然后从List(itemPrice)中找出最低值。

double lowest_price = itemPrice.Min(c => c.qtPrice);

然后声明一个新的List

List<qtInvoice> newItemPrice = new List<qtInvoice>();

将所有“lowest_price”添加到“newItemPrice”列表的第一个循环

foreach (var item in itemPriceDate)
            {
                if (item.qtPrice == lowest_price)
                {
                    newItemPrice.Add(item);
                }
            }

然后在第二个循环中将所有剩余价格添加到“newItemPrice”列表

foreach (var item in itemPriceDate)
            {
                if (item.qtPrice != lowest_price)
                {
                    newItemPrice.Add(item);
                }
            }