Как заказать список объектов с совпадающими ключами из другого списка? - PullRequest
1 голос
/ 28 мая 2020

Мне нужно отсортировать существующий список объектов на основе другого списка объектов (с совпадающими ключами), но оба списка могут содержать или не содержать одинаковые ключи и количество элементов. Пример:

struct Item 
{
    public string _id;
    public Item(string id) { _id = id; }
}

List<Item> totalItems = new List<Item>()
{
    new Item("foo"), new Item("bar"),
    new Item("baz"), new Item("monkey"),
    new Item("cat"), new Item("apple")
};

List<string> preferredSortOrder = new List<string>()
{
    "monkey",
    "cat",
    "zebra",
    "baz"
};

Таким образом, на выходе будет:

monkey
cat
baz
apple
bar
foo

Это потому, что порядок сортировки из PreferredSortOrder имеет приоритет, поэтому monkey, cat и baz идут первыми в списке, потому что они существуют в совокупности. Если чего-то в списке предпочтительныхSortOrder нет в totalItems, это следует игнорировать. Все оставшиеся элементы в totalItems следует затем упорядочить в алфавитном порядке (как вы можете видеть выше).

Я не программировал в linq годами, и все, что я пробовал до сих пор, не работает.

Изменить: на основе ответа Калимеро вот решение:

totalItems = totalItems
.OrderBy(item => item._id)
.OrderBy(item => {
    var i = preferredSortOrder.IndexOf(item._id);
    return i == -1 ? totalItems.Count : i;
}).ToList();

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Используйте метод List.IndexOf из вашего списка ссылок в качестве параметра функции keySelector для Enumerable.OrderBy с Linq.

totalItems.OrderBy(item => preferredSortOrder.IndexOf(item._id)).ToList();

EDIT: это поставит элементы, которых нет в списке ссылок первыми (поскольку IndexOf вернет -1). Но вы можете легко вернуть значение, превышающее любой возможный индекс для этого случая

totalItems.OrderBy(item => 
{ 
   var index = preferredSortOrder.IndexOf(item._id);
   return index == -1 ? totalItems.Count : index
}).ToList();

Вы можете сделать метод расширения из этого, если вы неоднократно использовали его.

EDIT 2: Я не обратил внимание на то, что ваш _id является частным (вы не указали доступность, и здесь она используется по умолчанию). Вы, вероятно, захотите иметь свойство, которое использует его в качестве вспомогательного поля, или сделать его publi c

0 голосов
/ 28 мая 2020
  1. Добавьте второе строковое поле в структуру Item, назовите его 'sortOrder'.
  2. Создайте класс или структуру для 'PreferredSortOrder', добавьте второе строковое поле ('sortOrder'), которое указывает Порядок сортировки. Используйте числа, так как они будут сортировать перед альфа-версией.
  3. Сделайте первый проход через 'totalItems', выполните поиск по 'предпочтительномуSortOrder', скопируйте sortOrder. Если элемент не найден, скопируйте его строку (например, «яблоко»).
  4. Сортировать totalItems в sortOrder. Престо!
...