代码之家  ›  专栏  ›  技术社区  ›  Tom W

LinkedList上的LINQ-遍历LinkedListNode<T>,而不是T

  •  6
  • Tom W  · 技术社区  · 14 年前

    我在理解如何在LINQ中做某事时遇到了问题。

    我有一个linkedlist,对象的类型无关紧要。重要的是我想在 Where() 基于当前对象之间的关系 名单上的下一个。

    为什么我不能这样做:

    linkedlist.Where(n=>a_function(n.Value, n.Next.Value))

    如果这是可能的,那么语法是什么呢?类型推理系统似乎坚持认为我希望lambda参数 T ,不是 LinkedListNode<T> .

    3 回复  |  直到 14 年前
        1
  •  15
  •   max    14 年前

    为此,您必须为链表编写新的迭代器。有点像

    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))
    
        2
  •  2
  •   Ani    14 年前

    你的问题与类型推断没有多大关系; LinkedList<T> 是一个 IEnumerable<T> ,不是 IEnumerable<LinkedListNode<T>> . 另外,没有 获取序列的方法 (current, next) 元组,所以你必须自己实现它。

    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) .

        3
  •  1
  •   Tim Pohlmann    6 年前

    受麦克斯回答的启发,我想出了一个较短的版本:

    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;