Как выбрать уникальные элементы из списка {0, 1, 2, 2, 2, 3, 4, 4, 5}
, чтобы я получил {0, 1, 3, 5}
, эффективно удалив все экземпляры повторяющихся элементов {2, 4}
?
Выбор уникальных элементов из списка в С#
Ответ 1
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 }
Ответ 2
var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();
убедитесь, что вы используете Linq и .NET framework 3.5.
Ответ 3
С лямбдой..
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);
Ответ 4
Решение С# 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;
}
}
Ответ 5
Вот еще один способ, который работает, если у вас есть сложные объекты типа в вашем списке и вы хотите получить уникальные значения свойства:
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();
}
}
Ответ 6
Если Linq недоступен для вас, потому что вам необходимо поддерживать устаревший код, который нельзя обновить, тогда объявите словарь, где первым будет число int, а второе int - количество вхождений. Прокрутите список, загрузив словарь. Когда вы закончите, прокрутите свой словарь, выбрав только те элементы, где число вхождений равно 1.
Ответ 7
Я считаю, что Мэтт хотел сказать:
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;
}
Ответ 8
Существует много способов скинуть кошку, но 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
Ответ 9
В .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;
}