LINQ对一个LinkedList - 叠代一个LinkedListNode ,不是T

问题描述 投票:6回答:3

我在了解如何做一些LINQ的一个问题。

我有一个链表,该对象的类型并不重要。什么事情确实是我想要做的事基于当前对象和下一个列表之间的关系Where()

为什么我不能做这样的事情:

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

什么是语法要做到这一点,如果它甚至有可能?该类型推断系统似乎坚持我想要的拉姆达参数是T,不LinkedListNode<T>

.net linq linked-list
3个回答
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))

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)过滤器。


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;
© www.soinside.com 2019 - 2024. All rights reserved.