gpt4 book ai didi

c# - 使用 LINQ 获取 IEnumerable 中的上一个和下一个项目

转载 作者:IT王子 更新时间:2023-10-29 04:10:17 25 4
gpt4 key购买 nike

我有一个自定义类型的 IEnumerable。 (我从 SelectMany 得到的)

我在那个 IEnumerable 中也有一个项目 (myItem),我希望 IEnumerable 中的上一个和下一个项目。

目前,我正在做这样的事情:

var previousItem = myIEnumerable.Reverse().SkipWhile( 
i => i.UniqueObjectID != myItem.UniqueObjectID).Skip(1).FirstOrDefault();

我可以通过简单地省略 .Reverse 来获得下一个项目。

或者,我可以:

int index = myIEnumerable.ToList().FindIndex( 
i => i.UniqueObjectID == myItem.UniqueObjectID)

然后使用 .ElementAt(index +/- 1) 获取上一个或下一个项目。

  1. 这两个选项哪个更好?
  2. 是否有更好的选择?

“更好”包括性能(内存和速度)和可读性的结合;可读性是我最关心的问题。

最佳答案

首先

"Better" includes a combination of performance (memory and speed)

一般来说你不能两者兼得,经验法则是,如果你优化速度,它会消耗内存,如果你优化内存,它会消耗你的速度。

有一个更好的选择,它在内存和速度方面都表现良好,并且可以以可读的方式使用(我对函数名称不满意,但是,FindItemReturningPreviousItemFoundItemAndNextItem 是一个有点含糊)。

所以,看起来是时候使用自定义查找扩展方法了,比如 . . .

public static IEnumerable<T> FindSandwichedItem<T>(this IEnumerable<T> items, Predicate<T> matchFilling)
{
if (items == null)
throw new ArgumentNullException("items");
if (matchFilling == null)
throw new ArgumentNullException("matchFilling");

return FindSandwichedItemImpl(items, matchFilling);
}

private static IEnumerable<T> FindSandwichedItemImpl<T>(IEnumerable<T> items, Predicate<T> matchFilling)
{
using(var iter = items.GetEnumerator())
{
T previous = default(T);
while(iter.MoveNext())
{
if(matchFilling(iter.Current))
{
yield return previous;
yield return iter.Current;
if (iter.MoveNext())
yield return iter.Current;
else
yield return default(T);
yield break;
}
previous = iter.Current;
}
}
// If we get here nothing has been found so return three default values
yield return default(T); // Previous
yield return default(T); // Current
yield return default(T); // Next
}

如果您需要多次引用项目,您可以将此结果缓存到列表中,但它会返回找到的项目,前面是前一个项目,然后是下一个项目。例如

var sandwichedItems = myIEnumerable.FindSandwichedItem(item => item.objectId == "MyObjectId").ToList();
var previousItem = sandwichedItems[0];
var myItem = sandwichedItems[1];
var nextItem = sandwichedItems[2];

如果它是第一个或最后一个项目,则返回的默认值可能需要根据您的要求进行更改。

希望这对您有所帮助。

关于c# - 使用 LINQ 获取 IEnumerable 中的上一个和下一个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8759849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com