假设我在c#中有某种类型的通用列表L
。然后,使用linq,在其上调用OrderBy()
,传入lambda表达式。
如果我重新分配L
,之前的订单操作显然会丢失。
在我重新分配之前,有什么方法可以“保存”我在列表中使用的lambda表达式,然后重新应用它?
答案 0 :(得分:2)
使用Func delegate存储您的订购,然后将其传递给OrderBy方法:
Func<int, int> orderFunc = i => i; // func for ordering
var list = Enumerable.Range(1,10).OrderByDescending(i => i); // 10, 9 ... 1
var newList = list.OrderBy(orderFunc); // 1, 2 ... 10
另一个例子考虑一个Person
类:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
现在您要保留按Name
属性排序的排序顺序。在这种情况下,Func
对Person
类型(T
)进行操作,而TResult
将是一个字符串,因为Name
是一个字符串,就是你的样子排序。
Func<Person, string> nameOrder = p => p.Name;
var list = new List<Person>
{
new Person { Id = 1, Name = "ABC" },
new Person { Id = 2, Name = "DEF" },
new Person { Id = 3, Name = "GHI" },
};
// descending order by name
foreach (var p in list.OrderByDescending(nameOrder))
Console.WriteLine(p.Id + ":" + p.Name);
// 3:GHI
// 2:DEF
// 1:ABC
// re-assinging the list
list = new List<Person>
{
new Person { Id = 23, Name = "Foo" },
new Person { Id = 14, Name = "Buzz" },
new Person { Id = 50, Name = "Bar" },
};
// reusing the order function (ascending by name in this case)
foreach (var p in list.OrderBy(nameOrder))
Console.WriteLine(p.Id + ":" + p.Name);
// 50:Bar
// 14:Buzz
// 23:Foo
编辑:确保在ToList()
调用之后添加OrderBy
如果需要List<T>
,因为LINQ方法将返回IEnumerable<T>
。
答案 1 :(得分:1)
在ToList()
上拨打ToArray()
或IEnumerable<T>
会立即对其进行评估。然后,您可以分配结果列表或数组以“保存”您的有序列表。
答案 2 :(得分:-1)
Func<List<int>, IEnumerable<int>> applyQuery = L => L.OrderBy(i => -i);
List<int> source = new List<int>(){1, 2, 5};
IEnumerable<int> query = applyQuery(source);
source = new List<int>() { 1, 2, 3 };
query = applyQuery(source);
foreach (int x in query)
{
Console.WriteLine(x);
}
输出:
3
2
1