How do I select the unique elements from the list {0, 1, 2, 2, 2, 3, 4, 4, 5}
so that I get {0, 1, 3, 5}
, effectively removing all instances of the repeated elements {2, 4}
?

- 34,835
- 7
- 69
- 104

- 10,409
- 8
- 46
- 56
-
At least outside of C# (I can't say for C# itself), the starting point isn't really a set if it contains duplicates. It might be a multi-set, or a list, or ... – Jonathan Leffler Nov 15 '08 at 16:24
10 Answers
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 }

- 44,911
- 16
- 83
- 88
-
4
-
2@Tymek: The OP wants to remove duplicates, leaving only those numbers which are unique in the original sequence. – Bryan Watts Feb 20 '12 at 04:10
-
I'm lost. The code you provided doesn't modify the original sequence called 'numbers'. – tymtam Mar 01 '12 at 01:36
-
1@Tymek: The OP asked to select the unique numbers, which implies creating a new sequence by examining the existing sequence. – Bryan Watts Mar 01 '12 at 03:11
-
In this case I don't understand your first comment. That's what HashSet would do if you create it from the 'numbers' variable you shown. It would contain only the unique values: 0,1,2,3,4,5. :/ – tymtam Mar 01 '12 at 05:47
-
Ha! I understood it now! {0,1,2,2,2,3,4,4,5} -> {0, 3}, not {0,1,2,3,4,5} – tymtam Mar 01 '12 at 05:56
-
3@Tymek: Very close. It would be {0, 1, 3, 5}, since only 2 and 4 repeat. But I think you get the idea. – Bryan Watts Mar 01 '12 at 05:57
var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();
make sure you're using Linq and .NET framework 3.5.

- 17,997
- 28
- 94
- 124
-
3
-
Oh, my mistake. I didn't notice you wanted to remove those duplicate entries. – CVertex Nov 15 '08 at 08:26
With lambda..
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);

- 6,405
- 8
- 47
- 61
-
Note that in order to use this solution with objects, where you want to get a list objects with a specific key/ field that's unique, you'll need to replace that final Select with a SelectMany: `.SelectMany(i => i)`, which will flatten the `IEnumerable
>` back down to an `IEnumerable – zcoop98 Mar 24 '21 at 00:22`. -
Yet another way to do this with objects or otherwise is to replace the Where and Select altogether with `.Select(x => x.FirstOrDefault())` (Gleaned from [this blog post](https://vmsdurano.com/various-ways-to-get-distinct-values-from-a-listt-using-linq/)). – zcoop98 Mar 24 '21 at 00:28
C# 2.0 solution:
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;
}
}

- 3,638
- 5
- 27
- 47

- 40,310
- 20
- 83
- 102
-
-
1This works but you need to change counts[item]++; into if (counts.ContainsKey(item)) counts[item]++; else counts.Add(item, 1); – Ozgur Ozcitak Dec 23 '08 at 09:27
Here is another way that works if you have complex type objects in your List and want to get the unique values of a property:
var uniqueValues= myItems.Select(k => k.MyProperty)
.GroupBy(g => g)
.Where(c => c.Count() == 1)
.Select(k => k.Key)
.ToList();
Or to get distinct values:
var distinctValues = myItems.Select(p => p.MyProperty)
.Distinct()
.ToList();
If your property is also a complex type you can create a custom comparer for the Distinct(), such as Distinct(OrderComparer), where OrderComparer could look like:
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();
}
}

- 5,427
- 4
- 39
- 48
-
1i liked this better. shorter and easier to read (subjective?) with the lamba expressions. – Bahamut Jul 26 '12 at 08:41
-
@EwaldStieger, he doesn't want to leave a single instance for every value, he wants to REMOVE ALL THE INSTANCES of the values that are present more than 1 time. So how the `Distinct()` can achieve this? (I'm surprised of the 8 upvotes since your answer doesn't resolve the issue correctly.) – Massimiliano Kraus Oct 26 '16 at 18:07
-
@MassimilianoKraus Yes you are correct. I missed that in my original answer and have updated it now – Atomic Star Oct 28 '16 at 06:57
If Linq isn't available to you because you have to support legacy code that can't be upgraded, then declare a Dictionary, where the first int is the number and the second int is the number of occurences. Loop through your List, loading up your Dictionary. When you're done, loop through your Dictionary selecting only those elements where the number of occurences is 1.

- 22,649
- 18
- 83
- 121
I believe Matt meant to say:
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;
}

- 94,622
- 24
- 146
- 218
-
This is the .NET 2.0 version of what CVertex posted. It also returns the duplicate elements. – Ozgur Ozcitak Dec 23 '08 at 09:26
-
No, I prefer leaving them (as the French said the English occasionally shot an admiral) pour encourager l'autres. – Robert Rossney Jan 19 '09 at 10:19
There are many ways to skin a cat, but HashSet seems made for the task here.
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 );
}
The output:
0 1 2 3 4 5

- 31,798
- 8
- 86
- 126
-
Thank you but I wanted to remove _all instances_ of duplicate elements from the _original list_, eg. `{0, 1, 1, 2, 2, 3} -> {0, 3}` – Ozgur Ozcitak Feb 20 '12 at 16:05
-
Here's a solution with no LINQ:
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
// This assumes the numbers are sorted
var noRepeats = new List<int>();
int temp = numbers[0]; // Or .First() if using IEnumerable
var count = 1;
for(int i = 1; i < numbers.Length; i++) // Or foreach (var n in numbers.Skip(1)) if using IEnumerable
{
if (numbers[i] == temp) count++;
else
{
if(count == 1) noRepeats.Add(temp);
temp = numbers[i];
count = 1;
}
}
if(count == 1) noRepeats.Add(temp);
Console.WriteLine($"[{string.Join(separator: ",", values: numbers)}] -> [{string.Join(separator: ",", values: noRepeats)}]");
This prints:
[0,1,2,2,2,3,4,4,5] -> [0,1,3,5]

- 31,798
- 8
- 86
- 126
In .Net 2.0 I`m pretty sure about this solution:
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;
}

- 81
- 1
- 1
-
1But this method adds every present value. He doesn't want this. He wants the duplicated values to be COMPLETELY REMOVED. – Massimiliano Kraus Oct 26 '16 at 18:09