我想计算 System.Collections.Generic.LinkedList 中起始节点和结束节点之间的节点总数,类似于STL算法 std :: count < / strong>在C ++中(除了我打算在计数中包含结束节点)。
我无法弄清楚,例如如何使用任何LINQ扩展方法来有效地计算这个数字,所以我实现了一个这样的计数器(不包括所有 null 和一致性检查):
var counter = 1;
var node = iStartNode;
while (!ReferenceEquals(node, iEndNode))
{
node = node.Next;
++counter;
}
但必须有一个更有效的解决方案,一定不是吗?任何建议都非常感谢。
答案 0 :(得分:6)
我相信您的解决方案是最有效的,也是最具可读性的。即使你能在LINQ中找到一个实现,它肯定会是曲折的。
通过排除null
检查,我认为你的意思是,如果node
在列表末尾运行,真正的代码就不会抛出。
答案 1 :(得分:4)
我能想到的唯一方法是略微更清洁 - 或者至少使一般代码使用链表节点稍微清洁一点 - 就是写两个扩展方法:
static IEnumerable<LinkedListNode<T>> AsEnumerable<T>
(this LinkedListNode<T> node)
{
// Can even call list.Head.AsEnumerable() when the list is empty!
while (node != null)
{
yield return node;
node = node.Next;
}
}
static IEnumerable<LinkedListNode<T>> ReverseEnumerable<T>
(this LinkedListNode<T> node)
{
while (node != null)
{
yield return node;
node = node.Previous;
}
}
然后你可以使用LINQ:
var count = node.AsEnumerable().TakeWhile(x => x != endNode).Count();
那不包括endNode
本身,所以您可能希望将其递增1.(如果TakeUntil
和SkipUntil
方法类似于{{1 }和TakeWhile
,但包括第一个谓词 - 非匹配节点作为最后一个要采取或跳过的节点。)
请注意,如果找不到SkipWhile
,就不会爆炸 - 它只会从开始节点开始计算列表的数量。
关于扩展方法的好处是它们基本上允许你在任何点上作为序列操作列表。