从列表中创建滑动窗口

问题描述 投票:3回答:2

我需要迭代列表,同时获取下一个和前一个项目。我现在这样做:

var items = collection.ToList();
for (int index = 0; index < items.Count; index++)
{
    var prevItem = index == 0 ? null : items[index - 1];
    var currentItem = items[index];
    var nextItem = (index + 1) == items.Count ? null : items[index + 1];
    // do work
}

这项工作,但它不如我想要的那么好和可读。是否有更可读的方法来创建滑动窗口?这不涉及所有丑陋的三元检查。我觉得有一个更友好的方式使用select,skip,take和default如果为空

c# linq
2个回答
1
投票

如果你希望它可以重复使用,那么使用生成器可以最好地解决这类问题恕我直言。

public static IEnumerable<(T PrevItem, T CurrentItem, T NextItem)>
        SlidingWindow<T>(this IEnumerable<T> source, T emptyValue = default)
{
    using (var iter = source.GetEnumerator())
    {
        if (!iter.MoveNext())
            yield break;
        var prevItem = emptyValue;
        var currentItem = iter.Current;
        while (iter.MoveNext())
        {
            var nextItem = iter.Current;
            yield return (prevItem, currentItem, nextItem);
            prevItem = currentItem;
            currentItem = nextItem;
        }
        yield return (prevItem, currentItem, emptyValue);
    }
}

然后使用它:

foreach (var (prevItem, currentItem, nextItem) in collection.SlidingWindow())
{
    // do stuff with prevItem, currentItem, nextItem
}

1
投票

使其更好的一种方法是在包含itemprevItemnextItem的对象列表中转换您的集合:

 static void Main(string[] args)
        {

            var collection = new List<string> { "A", "B", "C", "D", "E" };

            var items = collection.Select((item, index) => new
            {
                Item = item,
                PreVItem = index > 0 ? collection[index - 1] : null,
                NextItem = index < collection.Count-1 ? collection[index + 1] : null
            });

            foreach (var item in items)
            {
                Console.WriteLine($"{item.PreVItem} \t {item.Item} \t {item.NextItem}");
            }


            Console.ReadLine();
        }
© www.soinside.com 2019 - 2024. All rights reserved.