Почему в этом списке есть ошибка сортировки? - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть эти модели в системе для изображений и тегов изображений:

public class Image
{
    public int Id { get; set; }
    // some more properties...

    public List<ImageTag> Tags { get; set; }
}

public class ImageTag
{
    public int Id { get; set; }
    public int ImageId { get; set; }
    public string Tag { get; set; }
    public Image Image { get; set; }
}

Чтобы получить список из 10 наиболее часто используемых тегов, я выполняю этот запрос:

List<ImageTag> mostUsedTags =
    await db.Images
        .Select(t => t.Tags.OrderBy(o => o.ImageId).FirstOrDefault()).Take(10)
        .ToListAsync().ConfigureAwait(false);

// The list has the tags with the fewest images first, so I have to reverse it:
mostUsedTags.Reverse();

Список, который я получаю, имеет следующее количество изображений, связанных с ними: 4, 3, 2, 1, 2, 1, 1.

Почему четвертое и пятое место поменялись местами?

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Мне не совсем понятно, как вы определяете, используется ли тег более чем одним изображением, потому что отображение между двумя классами кажется немного "грязным" (как я описал в комментарии под вопросом).

Но если предположить, что свойство Tag - это свойство, которое мы использовали бы, чтобы увидеть, совпадают ли два объекта ImageTag, то вы можете сделать что-то подобное, чтобы получить наиболее часто используемые теги:

var mostUsedTags = images
    .SelectMany(i => i.Tags)           // Get all the ImageTags from all the images
    .GroupBy(t => t.Tag)               // Group them by the Tag property
    .OrderByDescending(g => g.Count()) // Order groups by their count (descending)
    .Take(10)                          // Take the top 10 results
    .Select(g => g.Count());           // Select the count associated with each tag

Вы также можете выбрать строку, в которой упоминается Tag, чтобы вы могли определить, какие теги являются самыми популярными:

.Select(g => $"'{g.Key}' is associated with {g.Count()} images");

или просто заменить .Select() на .ToList(), чтобы получить список всех объектов IGrouping, поэтому у вас есть все данные, связанные с каждой группой

0 голосов
/ 08 февраля 2020

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

Ваше предположение неверно, следующие порядки Tags на ImageId перед выбором первый элемент, затем , возвращающий список в любом порядке, который он выберет.

t.Tags.OrderBy(o => o.ImageId)

Я "догадываюсь", что вы хотите что-то подобное, хотя я не совсем уверен, что я правильно понимаю что вы хотите ...

.Images.OrderByDescending(x => x.Tags.Count)
       .Select(t => ...)...

или, может быть,

ImageTags.GroupBy(x => x.ImageId)
         .OrderByDescending(x => x.Count)
         .Select(t => ...)
         .Take(10)
...