如果我有:
List<Car>
汽车在哪里:
public class Car
{
public int Year;
public string Name;
}
我想接受这个数组并用“,”
创建一个连接的字符串所以它会返回:
"Toyota, Ford, Chevy"
我可以像这样手动完成:
private static string CreateConcatenatedList(List<Car> parts_)
{
StringBuilder b = new StringBuilder();
foreach (Car bp in parts_)
{
b.Append(bp.Name + ", ");
}
b.Remove(b.Length - 2, 2);
return b.ToString();
}
但我认为可能会有更优雅的方式
答案 0 :(得分:10)
List<Car> cars = //whatever;
string concat = String.Join(",", cars.Select(c => c.Name).ToArray());
编辑:如果您担心创建中间数组,也可以使用Aggregate:
string concat = cars.Select(c => c.Name).Aggregate(new StringBuilder(), (sb, current) =>
{
return sb.Length == 0 ? sb.Append(current) : sb.AppendFormat(",{0}", current);
}).ToString();
答案 1 :(得分:6)
因为您在对Lees的评论中询问是否更快/更慢或只是更少的代码。我试了一下,写了一个小车类:
public class Car
{
public string Name { get; set; }
public Car(string name) { Name = name; }
}
使用随机生成的长度为5-10的字符串对其进行测试:
private static Random random = new Random((int)DateTime.Now.Ticks);
private static string RandomString(int min, int max)
{
string str = "";
int size = random.Next(min, max + 1);
for (int i = 0; i < size; i++)
str += Convert.ToChar(Convert.ToInt32(
Math.Floor(26 * random.NextDouble() + 65)));
return str;
}
public static void MeassureTicks(int numberCars, int minLength, int maxLength)
{
// Generate random list
List<Car> cars = Enumerable.Range(0, numberCars)
.Select(x => new Car(RandomString(
minLength, maxLength))).ToList();
Stopwatch sw1 = new Stopwatch(), sw2 = new Stopwatch(),
sw3 = new Stopwatch(), sw4 = new Stopwatch();
sw1.Start();
string concat1 = CreateConcatenatedList(cars);
sw1.Stop();
sw2.Start();
string concat2 = String.Join(",", cars.Select(c => c.Name).ToArray());
sw2.Stop();
sw3.Start();
if (numberCars <= 5000)
{
string concat3 = cars.Select(c => c.Name).Aggregate("",
(str, current) =>
{
return str.Length == 0 ? str = current :
str += "," + current;
}).ToString();
}
sw3.Stop();
sw4.Start();
string concat4 = cars.Select(c => c.Name).Aggregate(
new StringBuilder(), (sb, current) =>
{
return sb.Length == 0 ? sb.Append(current) :
sb.AppendFormat(",{0}", current);
}).ToString();
sw4.Stop();
Console.WriteLine(string.Format("{0} car strings joined:\n" +
"\tYour method: {1} ticks\n" +
"\tLinq+String.Join: {2} ticks\n" +
"\tLinq+Aggregate+String.Concat: {3} ticks\n" +
"\tLinq+Aggregate+StringBuilder: {4} ticks\n",
cars.Count, sw1.ElapsedTicks, sw2.ElapsedTicks,
numberCars <= 5000 ? sw3.ElapsedTicks.ToString() : "-",
sw4.ElapsedTicks));
<强>更新强> 我现在正在尝试使用聚合的两种方法。
输出在我的电脑上用于不同数量的汽车:
5 car strings joined:
Your method: 14 ticks
Linq+String.Join: 20 ticks
Linq+Aggregate+String.Concat: 11 ticks
Linq+Aggregate+StringBuilder: 15 ticks
50 car strings joined:
Your method: 50 ticks
Linq+String.Join: 45 ticks
Linq+Aggregate+String.Concat: 70 ticks
Linq+Aggregate+StringBuilder: 73 ticks
500 car strings joined:
Your method: 355 ticks
Linq+String.Join: 348 ticks
Linq+Aggregate+String.Concat: 5365 ticks
Linq+Aggregate+StringBuilder: 619 ticks
5000 car strings joined:
Your method: 3584 ticks
Linq+String.Join: 3357 ticks
Linq+Aggregate+String.Concat: 379635 ticks
Linq+Aggregate+StringBuilder: 6078 ticks
50000 car strings joined:
Your method: 33705 ticks
Linq+String.Join: 34082 ticks
Linq+Aggregate+String.Concat: - ticks
Linq+Aggregate+StringBuilder: 92839 ticks
500000 car strings joined:
Your method: 508439 ticks
Linq+String.Join: 376339 ticks
Linq+Aggregate+String.Concat: - ticks
Linq+Aggregate+StringBuilder: 616048 ticks
Linq + String.Join
方法确实更快和更少的代码。与StringBuilter
一起聚合非常好(不像字符串连接),但速度稍慢。所以要么使用你的方法,要么使用Linq + String.Join
,这是一个很好的oneliner,也很容易阅读。
答案 2 :(得分:5)
List<Car> cars = ....
var result = string.Join(",", cars.Select(car => car.Name).ToArray());
答案 3 :(得分:1)
我认为你真正想要的是:
"Toyota, Ford, Chevy"
而不是:
"Toyota", "Ford", "Chevy"
如你的问题所述。这可以这样实现:
var cars = new List<Car>();
var delimitedString = string.Join(", ", cars.Select(c => c.Name).ToArray());
答案 4 :(得分:1)
ArrayList<Car> cars = ...
string finalValue = string.Join(",", cars.Select(c => c.Name).ToArray());
答案 5 :(得分:1)
我为这种情况编写了以下扩展方法。它使用字符串构建器和Aggregate而不是string.Join和一个数组来略微改进性能。
public static string Concatenate(
this IEnumerable<string> collection,
string separator)
{
return collection
.Skip(1)
.Aggregate(
new StringBuilder().Append(collection.First()),
(b, s) => b.Append(separator).Append(s))
.ToString();
}
然后在你的情况下它只是
cars.Select(c=>Name).Concatenate(", ");