Выбор уникальных элементов из списка в C#

Как мне выбрать уникальные элементы из списка {0, 1, 2, 2, 2, 3, 4, 4, 5}, чтобы получить {0, 1, 3, 5}, эффективно удалив все экземпляры повторяющихся элементов {2, 4}?

По крайней мере, за пределами C# (я не могу сказать о самом C#) начальная точка на самом деле не является набором, если он содержит дубликаты. Это может быть несколько наборов, или список, или ...

Jonathan Leffler 15.11.2008 19:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
23
1
53 690
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();

убедитесь, что вы используете Linq и .NET framework 3.5.

Это возвращает {0, 1, 2, 3, 4, 5}, включая повторяющиеся элементы.

Ozgur Ozcitak 15.11.2008 11:24

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

CVertex 15.11.2008 11:26
Ответ принят как подходящий
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };

var uniqueNumbers =
    from n in numbers
    group n by n into nGroup
    where nGroup.Count() == 1
    select nGroup.Key;

// { 0, 1, 3, 5 }

МОЙ БОГ. Это необычно. Как насчет HashSet <int> r = new HashSet <int> (числа);

tymtam 20.02.2012 07:20

@Tymek: OP хочет удалить дубликаты, оставив только те числа, которые уникальны в исходной последовательности.

Bryan Watts 20.02.2012 08:10

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

tymtam 01.03.2012 05:36

@Tymek: OP попросил выбрать уникальные числа, что подразумевает создание новой последовательности путем изучения существующей последовательности.

Bryan Watts 01.03.2012 07:11

В данном случае я не понимаю вашего первого комментария. Это то, что сделал бы HashSet, если бы вы создали его из показанной вами переменной «числа». Он будет содержать только уникальные значения: 0,1,2,3,4,5. : /

tymtam 01.03.2012 09:47

Ха! Я понял это теперь! {0,1,2,2,2,3,4,4,5} -> {0, 3}, а не {0,1,2,3,4,5}

tymtam 01.03.2012 09:56

@Tymek: Очень близко. Это будет {0, 1, 3, 5}, поскольку повторяются только 2 и 4. Но я думаю, вы уловили идею.

Bryan Watts 01.03.2012 09:57

Если Linq вам недоступен, потому что вам нужно поддерживать устаревший код, который нельзя обновить, объявите Dictionary, где первое int - это число, а второе int - количество вхождений. Прокрутите список, загрузив словарь. Когда вы закончите, прокрутите свой Словарь, выбирая только те элементы, у которых количество вхождений равно 1.

Решение C# 2.0:

static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
    Dictionary<T, int> counts = new Dictionary<T, int>();

    foreach (T item in things)
    {
        int count;
        if (counts.TryGetValue(item, out count))
            counts[item] = ++count;
        else
            counts.Add(item, 1);
    }

    foreach (KeyValuePair<T, int> kvp in counts)
    {
        if (kvp.Value == 1)
            yield return kvp.Key;
    }
}

Это вызовет исключение KeyNotFoundException

David Wengier 17.11.2008 12:46

Это работает, но вам нужно изменить counts [item] ++; в if (counts.ContainsKey (item)) counts [item] ++; иначе считается. Добавить (элемент, 1);

Ozgur Ozcitak 23.12.2008 12:27

Я считаю, что Мэтт хотел сказать:

 static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
 {
     Dictionary<T, bool> uniques = new Dictionary<T, bool>();
     foreach (T item in things)
     {
         if (!(uniques.ContainsKey(item)))
         {
             uniques.Add(item, true);
         }
     }
     return uniques.Keys;
 }

Это версия .NET 2.0 того, что опубликовал CVertex. Он также возвращает повторяющиеся элементы.

Ozgur Ozcitak 23.12.2008 12:26

Нет, я предпочитаю оставить их (как говорили французы, англичане иногда стреляли в адмирала) для поощрения l'autres.

Robert Rossney 19.01.2009 13:19

С лямбдой ..

var all = new[] {0,1,1,2,3,4,4,4,5,6,7,8,8}.ToList();
var unique = all.GroupBy(i => i).Where(i => i.Count() == 1).Select(i=>i.Key);

Обратите внимание, что для использования этого решения с объектами, где вы хотите получить список объектов с определенным ключом / полем, который уникален, вам необходимо заменить последний Select на SelectMany: .SelectMany(i => i), который сгладит IEnumerable<IGrouping<TKey, TElement>> обратно. к IEnumerable<T>.

zcoop98 24.03.2021 03:22

Еще один способ сделать это с объектами или иным образом - полностью заменить Where и Select на .Select(x => x.FirstOrDefault()) (позаимствовано из это сообщение в блоге).

zcoop98 24.03.2021 03:28

В .Net 2.0 я почти уверен в этом решении:

public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
     List<T> uniques = new List<T>();
     foreach (T item in source)
     {
         if (!uniques.Contains(item)) uniques.Add(item);
     }
     return uniques;
}

Но этот метод добавляет каждую текущую стоимость. Он этого не хочет. Он хочет, чтобы повторяющиеся значения были ПОЛНОСТЬЮ УДАЛЕНЫ.

Massimiliano Kraus 26.10.2016 21:09

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

var uniqueValues= myItems.Select(k => k.MyProperty)
                  .GroupBy(g => g)
                  .Where(c => c.Count() == 1)
                  .Select(k => k.Key)
                  .ToList();

Или получить отличные значения:

var distinctValues = myItems.Select(p => p.MyProperty)
                            .Distinct()
                            .ToList();

Если ваше свойство также является сложным типом, вы можете создать собственный компаратор для Distinct (), например Distinct (OrderComparer), где OrderComparer может выглядеть так:

public class OrderComparer : IEqualityComparer<Order>
{
    public bool Equals(Order o1, Order o2)
    {
        return o1.OrderID == o2.OrderID;
    }

    public int GetHashCode(Order obj)
    {
        return obj.OrderID.GetHashCode();
    }
}

мне это понравилось больше. короче и легче читать (субъективно?) с лямбда-выражениями.

Bahamut 26.07.2012 12:41

@EwaldStieger, он не хочет оставлять один экземпляр для каждого значения, он хочет УДАЛИТЬ ВСЕ ЭКЗЕМПЛЯРЫ значений, которые присутствуют более 1 раза. Так как же Distinct() может этого добиться? (Меня удивили 8 голосов, поскольку ваш ответ не решает проблему правильно.)

Massimiliano Kraus 26.10.2016 21:07

@MassimilianoKraus Да, вы правы. Я пропустил это в своем исходном ответе и обновил его сейчас

Ewald Stieger 28.10.2016 09:57

Есть много способов снять шкуру с кошки, но HashSet, похоже, предназначен для этой задачи.

var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };

HashSet<int> r = new HashSet<int>(numbers);

foreach( int i in r ) {
    Console.Write( "{0} ", i );
}

Выход:

0 1 2 3 4 5

Спасибо, но я хотел удалить все экземпляры повторяющихся элементов из исходный список, например. {0, 1, 1, 2, 2, 3} -> {0, 3}

Ozgur Ozcitak 20.02.2012 20:05

Как это объект класса List, который вы хотите изменить?

tymtam 01.03.2012 05:34

Другие вопросы по теме