我在理解如何在LINQ中执行某些操作时遇到问题。
我有一个链表,对象的类型无关紧要。重要的是我想根据当前对象与列表中下一个对象之间的关系在Where()
中做一些事情。
为什么我不能做类似的事情:
linkedlist.Where(n=>a_function(n.Value, n.Next.Value))
?
如果可能的话,执行此操作的语法是什么?类型推断系统似乎坚持我希望lambda参数为T
,而不是LinkedListNode<T>
。
答案 0 :(得分:15)
你必须为链表创建新的迭代器才能做到这一点。像
这样的东西public static class LinkedListExtensions
{
public static IEnumerable<LinkedListNode<T>> EnumerateNodes<T>(this LinkedList<T> list)
{
var node = list.First;
while(node != null)
{
yield return node;
node = node.Next;
}
}
}
所以你可以使用
linkedlist.EnumerateNodes().Where(n=>a_function(n.Value, n.Next.Value))
答案 1 :(得分:2)
您的问题与类型推断没有多大关系; LinkedList<T>
是IEnumerable<T>
,而不是IEnumerable<LinkedListNode<T>>
。此外,没有直接方法来获取(current, next)
元组的序列,因此您必须自己实现它。
这是LINQ的一种(效率不高)方式:
var filtered = linkedlist.Zip(linkedList.Skip(1),(current, next) => new {current, next} )
.Where(a => a_function(a.current, a.next))
.Select(a => a.current);
如果谓词与(value, nextValue)
匹配,则会选择一个值。如果这不完全符合您的需要,您可能需要稍微调整一下查询。
否则,如果您需要效率或者有许多基于(node, nextNode)
的过滤器,请使用max的解决方案。
答案 2 :(得分:0)
受max答案的启发,我想出了一个简短的版本:
public static IEnumerable<LinkedListNode<T>> GetNodes<T>(this LinkedList<T> list)
{
for (var node = list.First; node != null; node = node.Next)
yield return node;
}
或者您可以为更短的版本牺牲可读性:
public static IEnumerable<LinkedListNode<T>> GetNodes<T>(this LinkedList<T> list)
=> for (var node = list.First; node != null; node = node.Next) yield return node;