Сортировка списка объектов на основе того, насколько близко они сравниваются с другим объектом - PullRequest
1 голос
/ 10 декабря 2011

Вот мой объект пользователя:

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

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

User CurrentUser = Db.Users.Find((int)Session["UserId"]);

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

List<User> Users = Db.Users.Where(u => u.UserId != CurrentUser.UserId).ToList();

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

List<Tag> CurrentUserTags = new List<Tag>
{
    new Tag
    {
        TagId = 1
    },
    new Tag
    {
        TagId = 2
    },
    new Tag
    {
        TagId = 3
    }
}

Пользователь B имеет теги 1 и 2. Пользователь C имеет только тег 1. Я хочу отсортировать списокпользователей B следующим образом: пользователь B, затем пользователь C, поскольку список тегов пользователя B сравнивается более близко со списком тегов пользователя A, чем со списком пользователя C.

Я действительно надеюсь, что это имеет смысл, поскольку я полностью застрял.

Ответы [ 3 ]

2 голосов
/ 10 декабря 2011

Начните с использования Intersect

Users.OrderBy(o => o.Tags.Intersect(CurrentUser.Tags).Count)

Теперь это не сработает, потому что будут сравниваться ссылки на объекты Tag, где, как вам нужны идентификаторы.выбор либо реализации пользовательского оператора равенства, либо IEqualityComparer<T> и передачи этого.

public class TagComparer : IEqualityComparer<Tag>
{
    public bool Equals(Tag a, Tag b)
    {
        return a.TagId == b.TagId;
    }
}

Users.OrderBy(o => o.Tags.Intersect(CurrentUser.Tags, new TagComparer()).Count)
2 голосов
/ 10 декабря 2011

Создайте хэш-набор с идентификаторами из тегов:

var currentTags = new HashSet<int>(CurrentUserTags.Select(t => t.TagId));

Затем вы можете подсчитать теги, существующие в хэш-наборе:

Users = Users.OrderByDescending(
  u => u.Tags.Count(t => currentTags.Contains(t.TagId))
).ToList();
0 голосов
/ 10 декабря 2011

При сортировке списка по критериям я обычно использую интерфейс IComparer.

public class CompareUser : IComparer<User>
{
    public User o;

    public CompareUser(User p)
    {
        o = p;
    }

    public int Compare(User o1, User o2)
    {
        return (o1.Tags.Intersect(o.Tags).Count() < o2.Tags.Intersect(o.Tags).Count()) ?
            1 : -1;            
    }
}

затем используйте этот Comparer для сортировки списка.

CompareUser c = new CompareUser(CurrentUser);
Users.sort(c);

НТН.

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