c# выбрать экземпляр из списка классов на основе свойства - PullRequest
0 голосов
/ 06 мая 2020

Учитывая следующую структуру классов, необходимо извлечь различные элементы на основе значения настраиваемого свойства:

class Item{

    public Item(int position, Image image)
    {
        Position = position;
        Image = image;
    }

    public int Position { get; set; }
    public Image Image { get; set; }
    public int Quality { get; set; }
}

class Items : List<Item> {}
class ConsolidatedItems : List<Items> {}

Как получить список «лучших» Items на основе Качество , к которому присоединяется Позиция (другими словами сгруппировать элементы, где позиция одинакова):

Ввод

Items1:

Item1: 1, ImageBinary, 100
Item2: 2, ImageBinary, 98
Item3: 3, ImageBinary, 45
Item4: 4, ImageBinary, 66

Items2:
Item1: 1, ImageBinary, 76
Item2: 2, ImageBinary, 80
Item4: 4, ImageBinary, 33

Items3:
Item1: 2, ImageBinary, 76
Item2: 3, ImageBinary, 80
Item4: 4, ImageBinary, 90

Выход

BestItems:
Item1: 1, ImageBinary, 100 (from Items1)
Item2: 2, ImageBinary, 98 (from Items1)
Item3: 3, ImageBinary, 80 (from Items3)
Item4: 4, ImageBinary, 90 (from Items4)

Ответы [ 2 ]

2 голосов
/ 07 мая 2020

LINQ

var best = data
    .GroupBy(x => x.Position)
    .Select(x => x.Aggregate(
        (result, item) => item.Quality > result.Quality ? item : result)
    );
  • при условии, что data является коллекцией Item
  • , обязательно добавьте using System.Linq;
  • best - это IEnumerable, вы можете преобразовать его в список или массив, если вы sh используете ToList() или ToArray()

Редактировать на основе обсуждения : В если ваш data является экземпляром ConsolidatedItems, то есть вложенной коллекцией, вам нужно сначала сгладить ее, используя SelectMany:

var best = data
    .SelectMany(x => x)
    .GroupBy(x => x.Position)
    .Select(x => x.Aggregate(
        (result, item) => item.Quality > result.Quality ? item : result)
    );

Подробности

  1. data содержит ваши записи
  2. GroupBy создает коллекцию, в которой key является свойством или вычисленным значением, которое вы выбрали для группировки. Вы, конечно, можете перебирать все его элементы, что пригодится на следующих этапах.
  3. Select вычислит новую сущность для каждой группы - ту, которая имеет лучшее качество.
  4. Aggregate - пожалуй, самая сложная функция здесь. Он выполняет итерацию по членам группы и сохраняет в качестве результата один элемент. Результат инициализируется первым элементом. Затем Aggregate перемещается по всей коллекции и сравнивает каждый элемент с лучшим на данный момент результатом. В конце он возвращает результат с лучшим элементом.

Лучшая практика

Обратите внимание, что классы вашей коллекции плохо спроектированы. Посмотрите здесь почему бы не унаследовать форму List .

0 голосов
/ 07 мая 2020

Предполагая, что Position уже заполнен, вы можете использовать SelectMany, чтобы сгладить ваши ConsolidatedItems, сгруппировать их по позиции, упорядочить группы по позиции, а затем выбрать лучшее качество из каждой группы: 1003 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...