使用lambda,如何将现有函数应用于列表的所有元素?

时间:2017-04-08 00:39:33

标签: c# lambda

对不起,一个简单的问题:

我有一个字符串列表,字符串是一些文件的完整路径。我想只获得没有路径的文件名每个字符串的扩展名(以及更多地了解lambda)

基于How to bind a List to a DataGridView control?中的lambda表达式,我正在尝试类似下面的内容:

FilesName = Directory.GetFiles(fbd.SelectedPath).ToList(); // full path
List<string> FilesNameWithoutPath = AllVideosFileNames.ForEach(x => Path.GetFileNameWithoutExtension(x)); // I want only the filename
AllVideosGrid.DataSource = FilesNameWithoutPath.ConvertAll(x => new { Value = x }); // to then bind it with the grid

错误是:

  

无法将void()转换为字符串列表

所以我想对Path.GetFileNameWithoutExtension()中的每个字符串应用FilesName。并且非常感谢Lamba如何在这种情况下工作。

2 个答案:

答案 0 :(得分:3)

ForEach会对列表中的每个项目执行一些代码,但不会返回任何内容(请参阅:List<T>.ForEach Method)。你想要做的是Select方法的结果(参见:Enumerable.Select<TSource, TResult> Method),它看起来像:

List<string> FilesNameWithoutPath = AllVideosFileNames
    .Select(x => Path.GetFileNameWithoutExtension(x))
    .ToList(); 

答案 1 :(得分:1)

您正在使用List<T>.ForEach方法,它接受列表中的每个元素并将给定的函数应用于它们,但它不会返回任何内容。所以你所做的基本上是获取每个文件名并扔掉它们。

您需要的是Select而不是ForEach

var fileNamesWithoutPath = AllVideosFileNames
                              .Select(x => Path.GetFileNameWithoutExtension(x))
                              .ToList();
AllVideosGrid.DataSource =  fileNamesWithoutPath;

这将投影每个项目,将Path.GetFileNameWithoutExtension应用于它们并返回结果,然后按ToList将该结果放入列表中。

请注意,您也可以使用方法组缩短Select而不声明lambda变量:

.Select(Path.GetFileNameWithoutExtension)