已经有一段时间了,因为我使用了lambda表达式或LINQ,我想知道如何使用这两种方法执行以下操作(我知道我可以使用foreach循环,这只是出于好奇)。
我有一个字符串路径数组(如果这是一个数组或列表,它会有所不同吗?),我想从中返回一个只有文件名的新列表。
即。使用foreach循环它将是:
string[] paths = getPaths();
List<string> listToReturn = new List<string>();
foreach (string path in paths)
{
listToReturn.add(Path.GetFileName(path));
}
return listToReturn;
我如何对lambda和LINQ做同样的事情?
编辑:在我的情况下,我使用返回的列表作为ListBox(WPF)的ItemsSource,所以我假设它需要是一个列表而不是IEnumerable ?
答案 0 :(得分:15)
您的主要工具是.Select()方法。
string[] paths = getPaths();
var fileNames = paths.Select(p => Path.GetFileName(p));
如果这是一个数组或列表,它会有所作为吗?
不,数组也实现了IEnumerable<T>
请注意,此最小方法涉及延迟执行,这意味着fileNames
是IEnumerable<string>
,并且只有在从中获取元素时才开始迭代源数组。
如果你想要一个List(为了安全),请使用
string[] paths = getPaths();
var fileNames = paths.Select(p => Path.GetFileName(p)).ToList();
但是当有很多文件时,您可能希望通过使用延迟执行源来反向(使结果交错,更快):
var filePaths = Directory.EnumerateFiles(...); // requires Fx4
var fileNames = filePaths.Select(p => Path.GetFileName(p));
这取决于您在fileNames
下要执行的操作。
答案 1 :(得分:6)
我认为“LINQ”你的意思是“查询表达式”,但是:
// Query expression
var listToReturn = (from path in paths
select Path.GetFileName(path)).ToList();
// Extension methods and a lambda
var listToReturn = paths.Select(path => Path.GetFileName(path))
.ToList();
// Extension methods and a method group conversion
var listToReturn = paths.Select(Path.GetFileName)
.ToList();
注意最后一个是如何通过从方法组构造投影委托来完成的,如下所示:
Func<string, string> projection = Path.GetFileName;
var listToReturn = paths.Select(projection).ToList();
(以防万一不清楚。)
请注意 if 你不需要将它用作列表 - 如果只是想要迭代它,换句话说 - 你可以删除{ {1}}从这些方法中调用。
答案 2 :(得分:5)
只是:
var listToReturn = getPaths().Select(x => Path.GetFileName(x)).ToList();
正如其他答案中所述,如果您实际上不需要List<string>
,则可以省略ToList()
并简单地返回IEnumerable<string>
(例如,如果您只需要迭代它,IEnumerable<>
更好,因为避免创建其他字符串列表)
另外,假设Select()
方法接受委托,并且方法组和具有相同签名的委托之间存在隐式转换,则可以跳过lambda并执行:
getPaths().Select(Path.GetFileName)
答案 3 :(得分:4)
你可以这样做:
return getPaths().Select(Path.GetFileName);
答案 4 :(得分:1)
listToReturn = paths.ToList().Select(p => Path.GetFileName(p));