English 中文(简体)
当项目相等时从一个可数源中删除一个单个项目
原标题:Removing a single item from an enumerable source when the items are equal

假设我有一个无数的来源, 看起来像这个:

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

我希望能够编造一份LINQ声明,

"first", "first", "second"

注意只有第一组被删除。 我不在乎哪一个, 因为在我的案例中, 所有的 3 “ 先行” 都被认为是平等的 。 我尝试过 < code> 源代码 。 除了( new [ { “ 先行 ” ) < / code > (new [ ] { “ 先行 } ) < / code > (new] {\\ { “ 先行 ” } 之外, 这排除了所有实例 。

最佳回答
source
  .GroupBy(s => s)
  .SelectMany(g => g.Skip(1).DefaultIfEmpty(g.First()))

对于每一组,跳过该组的第一个元素,然后返回其余元素,除非它不会返回任何元素,在这种情况下,返回该组的第一个元素。


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

对于每一组,取第一个元素,取第三个元素 -- -- 总是跳过第二个元素。

问题回答

我认为Amy B S回答得到你非常接近的答案, 但是它不会去除在只有一个价值的情况下的价值, 我认为原始海报是在找这个价值的。

这里的扩展方法将删除请求项目的一个实例,即使这是最后一个实例。这反映了 LINQ 例外 () 调用, 但只删除了第一个实例, 不是所有实例 。

    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);
    }

Given: {"one", "two", "three", "three", "three"}
The call source.ExceptSingle("three") results in {"one", "two", "three", "three"}

Given: {"one", "two", "three", "three"}
The call source.ExceptSingle("three") results in {"one", "two", "three"}

Given: {"one", "two", "three"}
The call source.ExceptSingle("three") results in {"one", "two"}

Given: {"one", "two", "three", "three"}
The call source.ExceptSingle("four") results in {"one", "two", "three", "three"}

我找到了一个单班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, 以防我后来想要添加一个“ 数字要删除” 参数( 将 & gt; 1 更改为 & gt; 数字要重新移动 ) 。 YAGNI 和所有这一切, 但无论如何, 它和布林安一样可以读取 。

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));
}

在此快速地努力。 基本上, 这将从原始的列表中创建第二个列表, 包含每个不同的键和实例的数, 如果有一个以上的话, 扣除一个, 然后重编一个包含正确数字元素的列表 。

没有David B回答的优雅,但我已经写好了,尽管我或许可以把它张贴为另一个可能的答案。我相信每个答案都可以写成Linq语句,但很晚了,我的大脑也不行了!

我对LINQ并不非常熟悉, 但这里是您可能想要用于此的一般流 :

在新的列表B中存储所有独有项目,即:

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

成为

B: {1, 2, 4, 6}

通过 B 迭接,如果A 中存在,即删除A 中的一例,如果它存在,即:

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

成为

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

希望这有帮助!





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签