C#和LINQ,一次选择两个(连续)项目

You*_*Mom 8 c# linq

在有序集(数组,列表)上使用LINQ,有没有办法选择或以其他方式使用两个连续项?我在想象语法:

list.SelectTwo((x, y) => ...)
Run Code Online (Sandbox Code Playgroud)

xy位于索引项ii + 1列表/阵列英寸 可能没有办法做到这一点,我接受这种可能性,但我至少想说我试图找到答案.

我知道我可以使用其他东西和LINQ来实现这一点.

先感谢您.

The*_*kis 11

另一个答案是使用LINQ SkipZip.提供一个漂亮而干净的解决方案.

这是绝对正确的,但我想指出它列举了两次来源.根据每个用例的不同,这可能或不重要.如果它对你的情况很重要,这里有一个更长的替代方案,它在功能上等同,但列举了一次来源:

static class EnumerableUtilities
{
    public static IEnumerable<TResult> SelectTwo<TSource, TResult>(this IEnumerable<TSource> source,
                                                                   Func<TSource, TSource, TResult> selector)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (selector == null) throw new ArgumentNullException(nameof(selector));

        return SelectTwoImpl(source, selector);
    }

    private static IEnumerable<TResult> SelectTwoImpl<TSource, TResult>(this IEnumerable<TSource> source,
                                                                        Func<TSource, TSource, TResult> selector)
    {
        using (var iterator = source.GetEnumerator())
        {
            var item2 = default(TSource);
            var i = 0;
            while (iterator.MoveNext())
            {
                var item1 = item2;
                item2 = iterator.Current;
                i++;

                if (i >= 2)
                {
                    yield return selector(item1, item2);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

var seq = new[] {"A", "B", "C", "D"}.SelectTwo((a, b) => a + b);
Run Code Online (Sandbox Code Playgroud)

得到的序列包含"AB","BC","CD".


m3t*_*n0b 5

System.Linq.Enumerable.ZipIEnumerable通过将i每个的第 -th 个元素配对来组合两个s i。所以你只需要在Zip你的列表中使用它的转换版本。

作为一个不错的扩展方法:

using System.Collections.Generic;
using System.Linq;

static class ExtMethods
{
    public static IEnumerable<TResult> SelectTwo<TSource, TResult>(this IEnumerable<TSource> source,
                                                                        Func<TSource, TSource, TResult> selector)
    {
        return Enumerable.Zip(source, source.Skip(1), selector);
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

Enumerable.Range(1,5).SelectTwo((a,b) => $"({a},{b})");
Run Code Online (Sandbox Code Playgroud)

结果是:

(1,2) (2,3) (3,4) (4,5)
Run Code Online (Sandbox Code Playgroud)

  • 我不知道这件事。这很棒!我只想指出它枚举了两次源,这可能是也可能不是理想的(取决于具体情况)。 (2认同)