使用linq从字符串拆分中获取最后一个元素

时间:2017-09-22 17:53:49

标签: c# linq split

我有一个字符串(文件夹路径)并将其分割为一个字符(\),它产生子串的数组(单个文件夹)。 如何在一行LINQ查询中获取最后一个文件夹。

基本上将以下转换为单行LINQ查询。

var test = item.Split('\\');
var count = test.Length;
var folder = test[count - 2];

我对如何获取数组的计数然后在一行中指定count -2感到困惑。

3 个答案:

答案 0 :(得分:5)

我认为在这里使用LINQ没有任何好处,但这里有:

item.Split('\\').Reverse().Skip(1).First();

由于反转,这将比现有代码更糟糕。

答案 1 :(得分:1)

开箱即用,LINQ没有这样做的方法,您可以编写自己的扩展方法来做类似的事情,但查看Last()的源代码 - 哪个是最接近的你正在努力实现 - 它实际上与你正在做的事情非常相似:

        int count = list.Count;
        if (count > 0) return list[count - 1];

所以幕后没有任何魔力,在我看来,你应该保留你已经拥有的代码,因为它确实需要它,并且它清晰易懂,而不是创建一个不必要的扩展方法或复杂的LINQ查询

答案 2 :(得分:-1)

让我们充分热核这个答案只是为了好玩。我们可以使用LINQ创建单行查询,其性能可与您的解决方案相媲美,但我们必须首先创建几个扩展方法。

Split的问题在于它返回string[],我们真正需要的是IEnumerable<string>。是的,所有string[]都是IEnumerabl<string>,但并非所有IEnumerable<string>都是string[] - 我们真正感兴趣的是懒惰的评估,我们不会用{{1 }}。所以,让我们自己动手吧!

Split

你可以随心所欲地疯狂。添加重载以接受public static class StringExtensions { public static IEnumerable<string> SplitAsEnumerable(this string source, char splitter) { if (source == null) { yield break; } var builder = new StringBuilder(); foreach (char c in source) { if (c != splitter) { builder.Append(c); } else { if (builder.Length > 0) { yield return builder.ToString(); builder.Clear(); } } } } } char[]string以拆分字符串。用你的想象力。

现在这是一个很好的第一步,但我们需要能够让我们采用string[]的最后一个元素。 Interactive Extensions提供了IEnumerable扩展方法,但我们不希望出现任何问题。因此,让我们自己推动!

TakeLast

现在我们可以根据需要采用尽可能多的元素。

以上扩展方法看起来很棒!我确信可以进行一些优化,当然我们需要留意边缘情况,但这应该足以让我们开始。

现在我们可以使用扩展方法和LINQ。我们走了:

public static class EnumerableExtensions
{
    public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
    {
        var queue = new Queue<T>(count);
        if (source == null)
        {
            yield break;
        }
        foreach (var item in source)
        {
            if (queue.Count == count)
            {
                queue.Dequeue();
            }
            queue.Enqueue(item);
        }
        foreach (var item in queue)
        {
            yield return item;
        }
    }
}

你去了 - 你选择了倒数第二个子字符串,其运行时间为O(n),与你现有的解决方案相当,并且(可能)更好的空间复杂度,因为我们使用的var folder = item.SplitAsEnumerable('\\').TakeLast(2).FirstOrDefault(); 可能是小于Queue返回的数组(这取决于传递给Split的{​​{1}}。