Linq - «Сохранение» операции OrderBy (c #) - PullRequest
2 голосов
/ 30 сентября 2010

Предположим, у меня есть общий список L некоторого типа в c #.Затем, используя linq, вызовите OrderBy() для него, передав лямбда-выражение.

Если я затем переназначу L, предыдущая операция заказа, очевидно, будет потеряна.

Есть ли способ, которым я могу «сохранить» лямбда-выражение, которое я использовал в списке, прежде чем переназначить его и повторно применить?

Ответы [ 3 ]

2 голосов
/ 30 сентября 2010

Используйте делегат Func для сохранения вашего заказа, а затем передайте его в метод 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 голос
/ 30 сентября 2010

Вызов ToList() или ToArray() на вашем IEnumerable<T> приведет к немедленной оценке.Затем вы можете назначить результирующий список или массив, чтобы «сохранить» ваш упорядоченный список.

0 голосов
/ 30 сентября 2010
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
...