c# – 使用Linq查找连续重复的元素

假设我有一个包含Value类型对象的列表. Value具有Name属性
private List<Value> values = new List<Value> {
    new Value { Id = 0,Name = "Hello" },new Value { Id = 1,Name = "World" },new Value { Id = 2,new Value { Id = 3,new Value { Id = 4,Name = "a" },new Value { Id = 5,};

现在我想获得所有“重复”值的列表(name属性与前一个元素的name属性相同的元素).
在这个例子中,我想要一个包含两个元素“world”和“a”(id = 2和5)的列表.

这个事件可以用linq吗?
当然,我可以这样做.像这样:

List<Value> tempValues = new List<Value>();
String lastName = String.Empty();
foreach (var v in values)
{
    if (v.Name == lastName) tempValues.Add(v);
    lastName = v.Name;
}

但是因为我想在更复杂的环境中使用这个查询,所以可能有一个“linqish”解决方案.

解决方法

沿着这些方向不会有任何内置的东西,但如果你经常需要它,你可以推出一些定制但相当通用的东西:
static IEnumerable<TSource> WhereRepeated<TSource>(
    this IEnumerable<TSource> source)
{
    return WhereRepeated<TSource,TSource>(source,x => x);
}
static IEnumerable<TSource> WhereRepeated<TSource,TValue>(
    this IEnumerable<TSource> source,Func<TSource,TValue> selector)
{
    using (var iter = source.GetEnumerator())
    {
        if (iter.MoveNext())
        {
            var comparer = EqualityComparer<TValue>.Default;
            TValue lastValue = selector(iter.Current);
            while (iter.MoveNext())
            {
                TValue currentValue = selector(iter.Current);
                if (comparer.Equals(lastValue,currentValue))
                {
                    yield return iter.Current;
                }
                lastValue = currentValue;
            }
        }
    }
}

用法

foreach (Value value in values.WhereRepeated(x => x.Name))
    {
        Console.WriteLine(value.Name);
    }

您可能想要考虑如何处理三元组等 – 目前除了第一个之外的所有内容都将被生成(与您的描述相符),但这可能不太正确.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...