Используйте LINQ для перемещения объекта в верхнюю часть списка

Я не уверен в скрытом, но существуют [приблизительно 110] интересные 'приемы' , которые, вероятно, не очевидны из просто чтения спецификации.

77
задан p.campbell 19 March 2012 в 21:31
поделиться

4 ответа

LINQ эффективен в запросах коллекций, создании прогнозов по существующим запросам или создании новых запросов на основе существующих коллекций. Он не предназначен для использования в качестве инструмента для встроенного переупорядочения существующих коллекций. Для этого типа операций лучше всего использовать тип на hande.

Предполагая, что у вас есть тип с таким же определением, как показано ниже

class Item {
  public int Id { get; set; }
  ..
}

Затем попробуйте следующее

List<Item> list = GetTheList();
var index = list.FindIndex(x => x.Id == 12);
var item = list[index];
list[index] = list[0];
list[0] = item;
48
ответ дан 24 November 2019 в 10:44
поделиться

По чему вы хотите заказать, кроме известного верхний пункт? Если вам все равно, вы можете сделать следующее:

var query = allCountries.OrderBy(x => x.id != 592).ToList();

Обычно «false» предшествует «true» ...

По общему признанию, я не знаю, что это делает в LINQ to SQL и т. Д. Возможно, вам понадобится запретить ему выполнять упорядочивание в базе данных:

var query = allCountries.AsEnumerable()
                        .OrderBy(x => x.id != 592)
                        .ToList();
138
ответ дан 24 November 2019 в 10:44
поделиться

Linq обычно работает с Enumerables, поэтому теперь, когда базовый тип не является коллекцией. Поэтому для перемещения элемента в начало списка я бы предложил использовать что-то вроде (если вам нужно сохранить порядок)

var idx = myList.FindIndex(x => x.id == 592);
var item = myList[idx];
myList.RemoveAt(idx);
myList.Insert(0, item);

Если ваша функция возвращает только IEnumerable, вы можете использовать метод ToList () чтобы сначала преобразовать его в список

Если вы не сохраняете порядок, вы можете просто поменять местами значения в позиции 0 и позиции idx

39
ответ дан 24 November 2019 в 10:44
поделиться

Вот метод расширения, который вы, возможно, захотите использовать. Он перемещает элемент (ы), который соответствует заданному предикату, наверх, сохраняя порядок.

public static IEnumerable<T> MoveToTop(IEnumerable<T> list, Func<T, bool> func) {
    return list.Where(func)
               .Concat(list.Where(item => !func(item)));
}

С точки зрения сложности, я думаю, что он сделает два прохода по коллекции, что сделает ее O (n), как Insert / Remove версия, но лучше, чем предложение Джона Скита OrderBy.

9
ответ дан 24 November 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: