2

This is probably easy for someone more experienced with LINQ and the Lambda expressions in C#. I'm just starting out with them, so I must be missing something.

I have a custom object like this:

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

Then, I have a list of these objects:

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

I want to convert this into a list of string with the Name property of the BusinessName object:

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

Obviously, I could do this:

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

But, I want to try using the lambda expressions with LINQ so that I can put this into a one liner.

So, I tried:

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

This works as expected, but is much slower than the foreach loop by 2x. I suspect this is because it's iterating the list twice, unlike the foreach loop.

So, I started looking for an alternative. I found Concat() but couldn't figure out how it was any different than AddRange().

Does anyone know a way to do this in one pass with LINQ?


inter process communication in python

I have a cloud process which downloads certain files to the cloud. How can I let my mother process know about success or failure to do some clean up work if required?

Should I be using semaphores?

Oh an something else, my cloud process never ends, so I can't exercise a .join()

4

5 回答 5

1

如果names是空的,你要做的是:

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

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

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;
于 2013-08-21T21:09:52.513 回答
1
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();
}
于 2013-08-21T21:40:00.340 回答
1

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

businessNames.ForEach(bn => names.Add(bn.Name));
于 2013-08-21T21:23:14.000 回答
1

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

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>容量设置为所需的项目数量可能会更快。

于 2013-08-21T21:34:52.283 回答
0
List<string> names = (from b in buisnessNames select b.Name).ToList();

或类似的东西...

于 2013-08-21T21:24:31.210 回答