如何在Linq / C#列表中获取当前和当前之后的项目?
我有一个项目列表,如果我选择一个项目,那么我将提供上一个和下一个选项。 我已经添加了一个快速代码示例,但我希望有更好/更快的方法来执行此示例,例如500个项目。
可能有一个linq选项或什么?
我检查了enumarator,但只有一个moveNext en无法设置当前。
快速举例:
项目是一本字典
project是字典中存在的keyvaluepair
var match = false; var save = new KeyValuePair(); var before = new KeyValuePair(); var after = new KeyValuePair(); foreach (var p in projects) { before = save; save = p; if (match) { after = p; break; } if (p.Key.Id == project.Key.Id) { match = true; } }
LINQ没有内置任何东西,但你可以很容易地编写自己的…这里是一个使用.NET 4中的Tuple
的实现。它将为一个最初有n个项目的序列返回n-2项 – 但你可以如有必要,请调整
public IEnumerable> WithNextAndPrevious (this IEnumerable source) { // Actually yield "the previous two" as well as the current one - this // is easier to implement than "previous and next" but they're equivalent using (IEnumerator iterator = source.GetEnumerator()) { if (!iterator.MoveNext()) { yield break; } T lastButOne = iterator.Current; if (!iterator.MoveNext()) { yield break; } T previous = iterator.Current; while (iterator.MoveNext()) { T current = iterator.Current; yield return Tuple.Create(lastButOne, previous, current); lastButOne = previous; previous = current; } } }
请注意,根据LukeH的回答,词典是无序的……但希望无论如何上述内容都会对你有所帮助。
你尝试过使用IndexOf()
和ElementAt()
方法吗?
Int32 index = list1.IndexOf(item); var itemPrev = list1.ElementAt(index - 1); var itemNext = list1.ElementAt(index + 1);
“ current
”之前的项目:
items.TakeWhile(x => x != current).LastOrDefault();
“ current
”之后的项目:
items.SkipWhile(x => x != current).Skip(1).FirstOrDefault();
适用于整数类型,但将在序列的末尾返回default(T)
。 将项目转换为Nullable
可能很有用,这样在第一个项目之前和最后一个项目之后返回null
。
字典没有内在的顺序,因此上一个和下一个项目的想法几乎是荒谬的。
我同意关于字典排序的其他意见。 但是,由于字典提供IEnumerable
,至少有一个小论点可以说它们有某种顺序。 无论如何,这是我的建议:
var ll = new LinkedList(); var qs = from p in projects let node = ll.AddLast(p.Key) select new { Project = p, Node = node, }; var lookup = qs.ToDictionary(q => q.Project, q => q.Node); var current = (ExtendedProjectLightPlan)null; //Whatever the current one is. var previous = lookup[current].Previous.Value; var next = lookup[current].Next.Value;
这应该使从任何项目移动到上一个或下一个项目非常简单 – 而且速度非常快。 (虽然速度不应该是一个问题,因为这是用户界面,对吧?)