使用C#LINQ将过滤后的List<;对象>;到列表<;字符串>;

本文关键字:gt lt 过滤 列表 字符串 对象 C#LINQ List 使用 | 更新日期: 2023-09-27 18:28:28

对于对C#中的LINQ和Lambda表达式更有经验的人来说,这可能很容易。我刚开始和他们在一起,所以我一定错过了什么。

我有一个像这样的自定义对象:

public class BusinessName {
    public string Name { get; set; }
    public string Type { get; set; }
}

然后,我有一个这些对象的列表:

List<BusinessName> businessNames = new List<BusinessName>();

我想将其转换为具有BusinessName对象的Name属性的string列表:

List<string> names = new List<string>();

显然,我可以这样做:

foreach (BusinessName name in businessNames) {
    names.Add(name.Name);
}

但是,我想尝试将lambda表达式与LINQ一起使用,这样我就可以将其放入一行中。

所以,我尝试了:

names.AddRange(businessNames.Select(item => item.Name));

这与预期的一样有效,但比foreach循环慢2倍。我怀疑这是因为与foreach循环不同,它对列表进行了两次迭代。

所以,我开始寻找另一种选择。我找到了Concat(),但不知道它和AddRange()有什么不同。

有人知道用LINQ一次性完成这项工作的方法吗?

使用C#LINQ将过滤后的List<;对象>;到列表<;字符串>;

如果names为空,则需要执行以下操作:

var names = businessNames.Select(item => item.Name).ToList();

另一种选择是使用List<T>ConvertAll方法,如下所示:

var names = buisnessNames.ConvertAll(item => item.Name);

然而,如果它可能不是空的,您也需要使用if语句:

var names = new List<string>();
//some code
if (names.Any())
    names.AddRange(/*your selected method*/);
else
    names = //your selected method;

您可以尝试在循环之前手动扩展List<string>容量,使foreach解决方案更快:

var newList = new List<string>(names.Count + businessNames.Count);
newList.AddRange(names); // will perform `Array.Copy` on underlying array //
foreach (BusinessName name in businessNames) {
    newList.Add(name.Name);
}
names = newList; // replace old list with a new one //

当您调用Add时,会执行一个检查,以确保底层数组足够大,可以再包含一个元素。如果不是,它会通过创建新值、复制所有值并替换来扩展。当你添加大量项目时,这种情况可能会发生多次。只提供帮助并将初始List<string>容量设置为所需的项目数量可能会更快。

public class BusinessName {
    public string Name { get; set; }
    public string Type { get; set; }
}
void Main()
{
    List<BusinessName> businessNames = new List<BusinessName>();
    List<string> names = new List<string>();
    names=names.Concat(businessNames.Select(b=>b.Name)).ToList();
}

因为businessNames是一个列表,所以可以使用List.ForEach:

businessNames.ForEach(bn => names.Add(bn.Name));
List<string> names = (from b in buisnessNames select b.Name).ToList();

或者类似的。。。