Проверка наличия того же объекта в списке

2

Вот история:

Я пытаюсь составить список разных кластеров... Я хочу только иметь необходимые кластеры... И кластеры могут быть одинаковыми.

Как я могу добавить это в список, проверяя, содержит ли этот список объект (я знаю, что объекты не могут быть переданы здесь)

Это моя цитата:

foreach (Cluster cluster in clustersByProgramme)
{
    if (!clusterList.Contains(cluster))
    {
        clusterList.Add(cluster);
    }
}
Теги:
list

5 ответов

8

Ваш код должен работать; если это не так, вы можете использовать разные экземпляры объектов, которые представляют один и тот же фактический кластер, и вы, возможно, не предоставили подходящую реализацию Equals (вы также должны обновить GetHashCode на то же время).

Также - в .NET 3.5 это может быть просто:

var clusterList = clustersByProgramme.Distinct().ToList();

В качестве примера класса, который поддерживает тесты равенства:

class Cluster // possibly also IEquatable<Cluster>
{
    public string Name { get { return name; } }
    private readonly string name;
    public Cluster(string name) { this.name = name ?? ""; }
    public override string ToString() { return Name; }
    public override int GetHashCode() { return Name.GetHashCode(); }
    public override bool Equals(object obj)
    {
        Cluster other = obj as Cluster;
        return obj == null ? false : this.Name == other.Name;
    }
}
  • 0
    +1. Это хороший момент по поводу Equals / HashCode.
  • 0
    Бонус за создание поля имени только для чтения, это правильный способ переопределить GetHashCode (), без разрушения мира;)
Показать ещё 6 комментариев
3

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

Предикат является делегатом метод, который возвращает true, если объект пройденный ему соответствует условиям определенных делегатом. Элементы текущего списка индивидуально передан делегату Predicate, и обработка прекращается, когда совпадение найдено.

Этот метод выполняет линейный поиск; поэтому этот метод является O (n) где n - количество.

2

Если вы используете .NET 3.5, используйте HashSet для этого.

HashSet<Cluster> clusterList = new HashSet<Cluster>();
foreach (Cluster cluster in clustersByProgramme)
{
     clusterList.Add(cluster);
}

В этом случае также убедитесь, что если cluster1 == cluster2, то

cluster1.Equals(cluster2);
cluster2.Equals(cluster1); //yeah, could be different depending on your impl
cluster1.GetHashCode() == cluster2.GetHashCode();
  • 0
    HashSet<T> не будет работать - список OP может содержать дубликаты, но не определенные дубликаты.
  • 0
    Да, это сработает - он не хочет добавлять дубликаты.
Показать ещё 2 комментария
0

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

Это n (1), пока ваши предметы имеют хороший хэш.

Кажется простым решением

Ie dictionary.Contains(key) - n (1)

вы можете обновить существующий, если вообще, или добавить новый

0

Ваш код верен, но он не очень эффективен. Вместо этого вы можете использовать HashSet<T> следующим образом:

HashSet<Cluster> clusterSet = new HashSet<T>();
foreach (Cluster cluster in clustersByProgramme)
  clusterSet.Add(cluster);

В этом случае также убедитесь, что если cluster1 == cluster2, то

cluster1.Equals(cluster2);
cluster2.Equals(cluster1); //yeah, could be different depending on your impl
cluster1.GetHashCode() == cluster2.GetHashCode();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню