我有一个字符串(文件夹路径)并将其分割为一个字符(\),它产生子串的数组(单个文件夹)。 如何在一行LINQ查询中获取最后一个文件夹。
基本上将以下转换为单行LINQ查询。
var test = item.Split('\\');
var count = test.Length;
var folder = test[count - 2];
我对如何获取数组的计数然后在一行中指定count -2感到困惑。
答案 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}}。