如何使用linQ访问列表中前一项?

h6my8fg2  于 2023-02-01  发布在  其他
关注(0)|答案(6)|浏览(144)

我有:

List<int> A  = new List<int>(){1,2,3,4,5,6};

List<int> m=new List<int>();
for(int i=1;i<A.count;i++)
{
int j=A[i]+A[i-1];
m.add(j);
}

我如何使用LinQ来执行相同的操作?

nbysray5

nbysray51#

简单的翻译就是:

var m = Enumerable.Range(1, A.Count - 1)
                  .Select(i => A[i] + A[i - 1])
                  .ToList();

但也要考虑:

var m = A.Skip(1)
         .Zip(A, (curr, prev) => curr + prev)
         .ToList();

或者使用Jon Skeet的扩展名:

var m = A.SelectWithPrevious((prev, curr) => prev + curr)
         .ToList();

但正如Jason Evans在评论中指出的,考虑到现有代码是完全可理解的(而且很短),而且无论如何都希望将“所有”结果物化为列表,这对可读性或简洁性没有太大帮助。
其实没有什么不对的:

var sumsOfConsecutives = new List<int>();

for(int i = 1; i < A.Count; i++)
   sumsOfConsecutives.Add(A[i] + A[i - 1]);
7qhs6swi

7qhs6swi2#

好了,现在可以使用列表中的下一项:

A.SkipWhile(x => x != value).Skip(1).FirstOrDefault();

因此,要获得前一项用途:

var B = A.ToList();
B.Reverse();
B.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
gopyfrb3

gopyfrb33#

不如这样

var l = A.Skip(1).Select((x, index) => x + A[index]).ToList();
aiqt4smr

aiqt4smr4#

其他一些答案假设A的元素总是1、2、3、4、5、6,如果这些值发生变化,那么解就会破裂,例如值变为2、3、6、7、10。
这是我的解,它适用于任何A值.

List<int> m = A.Skip(1).Select((element, index) => element + A.ElementAt(index)).ToList();

值得注意的是,坚持使用循环可能比为此拼凑一个Linq解决方案要好。

xuo3flqw

xuo3flqw5#

如果你只需要结束值,你可以聚合它,即。你需要以前的值,但不需要每个单独的值到一个新的列表。

int last = 0;
var r = m.Aggregate(last, (acc, it) => (last += it), (acc) => (last));
nfs0ujit

nfs0ujit6#

另一种选择是实现您自己的Buffer运算符,并使用该运算符生成简单的LINQ语句。

public static IEnumerable<IEnumerable<T>> Buffer<T>(this IEnumerable<T> source, int size)
{
    var buffer = new List<T>();
    foreach (var t in source)
    {
        buffer.Add(t);
        if (buffer.Count() == size)
        {
            yield return buffer.AsEnumerable();
            buffer = buffer.Skip(1).ToList();
        }
    }
}

允许以下代码:

List<int> B = A.Buffer(2).Select(x => x.Sum()).ToList();

相关问题