Removing one item from an enumerated source when items are equal

Suppose I have an enumerated source that looks like this:

IEnumerable<string> source = new [] { "first", "first", "first", "second" };

I want to be able to build a LINQ statement that will return this:

"first", "first", "second"

Please note that only one of the first has disappeared. I don’t care which one, because in my case all 3 “firsts” are considered equal. I tried source.Except(new [] { "first" }), but this excludes all instances.

+3
source share
5 answers
source
  .GroupBy(s => s)
  .SelectMany(g => g.Skip(1).DefaultIfEmpty(g.First()))

For each group, skip the first element of the group and return the rest - unless it returns to anyone ... in this case, return the first element of the group.


source
  .GroupBy(s => s)
  .SelectMany(g => g.Take(1).Concat(g.Skip(2)))

on - .

+8

, , , , , , , .

, , . LINQ Except(), , .

    public static IEnumerable<T> ExceptSingle<T>(this IEnumerable<T> source, T valueToRemove)
    {
        return source
            .GroupBy(s => s)
            .SelectMany(g => g.Key.Equals(valueToRemove) ? g.Skip(1) : g);
    }

: {"one", "two", "three", "three", "three"}
source.ExceptSingle("three") {"one", "two", "three", "three"}

: {"one", "two", "three", "three"}
source.ExceptSingle("three") {"one", "two", "three"}

: {"one", "two", "three"}
source.ExceptSingle("three") {"one", "two"}

: {"one", "two", "three", "three"}
source.ExceptSingle("four") {"one", "two", "three", "three"}

+6

LINQ , . . :

public static IEnumerable<T> ExceptOne<T>(this IEnumerable<T> enumerable, T element)
{
    var i = 0;

    return enumerable.Where(original => !EqualityComparer<T>.Default.Equals(original, element) || ++i > 1);
}

int, numberToRemove ( > 1 a > numberToRemove). YAGNI , , .

+3
IEnumerable<string> source = new [] { "first", "first", "first", "second" };

List<string> newSource = new List<string>();

var foo = source.GroupBy (s => s).Select (s => new KeyValuePair<string,int>(s.Key, (s.Count()>1)?s.Count()-1:s.Count ()));

foreach (var element in foo)
{
    newSource.AddRange(Enumerable.Repeat(element.Key,element.Value));
}

. , , , , .

, , , . , foreach Linq, , !

+1

LINQ, , :

B i.e.:

A: {1, 1, 1, 2, 4, 4, 6}

B: {1, 2, 4, 6}

B, A, i.e.:

A: {1, 1, 1, 2, 4, 4, 6}

F: {1, 1, 2, 4, 6}

, !

0

All Articles