7

I have:

List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" };

How can I get only "a","b"?

I tried to do like this:

List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" };
List<string> test_list = new List<string>(); 

test_list = list.Distinct().ToList();

Now test_list has {"a", "b", "r", "t"}
And then:

test_list = test_list.Except(list).ToList();

So that was my fail point, cause Except() deleted all elements.

Could you help me with solution?

Monopompom
  • 161
  • 2
  • 2
  • 12
  • 1
    Take a look at the `GroupBy` method. – Oded Apr 07 '13 at 19:29
  • Totally expected behavior. Except() excepted from test_list all entries found in list. What are you trying to do? – Tommi Apr 07 '13 at 19:30
  • It's a final bachelor work =) I'm doing a system with word search from data base by chosen filter – Monopompom Apr 07 '13 at 19:36
  • Alex, since [the @Sachin's answer](http://stackoverflow.com/a/15866810/200449) is the best, as you noted in comment to it, you should accept it as answer by clicking on the left of that answer the shallow check mark helping others to understand that the question was answered – Gennady Vanin Геннадий Ванин Apr 13 '13 at 05:25

6 Answers6

16
List<string> list = new List<string>() { "a", "a", "b", "b", "r", "t" };

var dups = list.GroupBy(x => x)
    .Where(x => x.Count() > 1)
    .Select(x => x.Key)
    .ToList();
I4V
  • 34,891
  • 6
  • 67
  • 79
10
var list = new List<string> { "a", "a", "b", "b", "r", "t" };

var distinct = new HashSet<string>();    
var duplicates = new HashSet<string>();

foreach (var s in list)
    if (!distinct.Add(s))
        duplicates.Add(s);

// distinct == { "a", "b", "r", "t" }
// duplicates == { "a", "b" }
dtb
  • 213,145
  • 36
  • 401
  • 431
  • 2
    +1 probably the most efficient approach. – Tim Schmelter Apr 07 '13 at 20:23
  • @TimSchmelter This is very good if you always want all the duplicate entries.. I have provided a bit more efficient (and lazy as well) solution here: https://stackoverflow.com/a/72647392/661933 – nawfal Jun 16 '22 at 14:22
8

Try this

var duplicates = list.GroupBy(a => a).SelectMany(ab => ab.Skip(1).Take(1)).ToList();
Sachin
  • 40,216
  • 7
  • 90
  • 102
3

A simple approach is using Enumerable.GroupBy:

var dups = list.GroupBy(s => s)
               .Where(g => g.Count() > 1)
               .Select(g => g.Key);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0
var duplicates = list.GroupBy(s => s).SelectMany(g => g.Skip(1).Take(1)).ToList();
Sergei G
  • 1,550
  • 3
  • 24
  • 44
0
var duplicates = list.GroupBy(a => a).SelectMany(ab => ab.Skip(1).Take(1)).ToList();

It will be more efficient then the one using Where(g => g.Count() > 1) and will return only one element from every group.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263