数字列表最低值在前,然后按输入日期
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);
}
}
所以我有一个来自数据库的价格列表。我想对其进行排序,以便列表中的第一个条目是编号最小的条目。然后所有其他条目都按输入日期排序。 如何做到这一点?
这是我的代码,有点乱,对不起,我正在尝试:)
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);
}
}