不使用 string.Join,如何将一个字符串数组连接起来?

6

这个问题仅用于学术目的。

假设我有以下代码...

var split = line.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
var elem = new XElement("shop");
elem.SetAttributeValue("name", split.Take(split.Length - 1));  <=====
elem.SetAttributeValue("tin", split.Last());

我希望您能够把箭头所指的行产生与这个相同的结果...
string.Join(string.Empty, split.Take(split.Length - 1));

不使用string.Join,能否将字符串数组转换为一个字符串?

有没有LINQ语句可以实现这个功能呢?希望大家已经知道!


2
有趣的答案,但我很好奇,为什么你要寻找不同于string.Join的方法呢?而且,你说你正在寻找一个Linq语句,但是你接受的答案(确实是一个好答案)根本没有使用Linq :) - Wasp
@Wasp,再次强调这个问题是学术性的。此外,我的意思是__不__要求通过LINQ来解决它,而更多地是因为我___认为___那是最好的方法,所以一直在寻找一个LINQ语句来完成它。然而,最终Guffa向我展示了一种更完美的方式。 - Mike Perrenoud
1
因此,问题应该是 - 我如何忽略该字符串的最后一段并去除逗号。你很幸运得到了你所需要的答案,但并非你所提出的问题的答案。 - D Stanley
@DStanley,你说得对。我的朋友,我很抱歉。这仍然是一个非常好的答案,这就是为什么我点了+1的原因。 - Mike Perrenoud
5个回答

6

使用 StringBuilder 实现 O(n) 性能:

split
    .Take(split.Length - 1)
    .Aggregate(new StringBuilder(), (sb, s) => sb.Append(s)).ToString();

如果目的是避免使用组合LINQ调用和静态方法时出现的不便,那么一个简单直接的解决方案是使用扩展方法:

public static string Join(this IEnumerable<string> self, string separator = "")
{
    return string.Join(separator, self);
}

然后:
split.Take(split.Length - 1).Join();

我发现在复杂的表达式中使用 string.Join 不如这种方式读起来更舒服。


4

不要使用Split,只需定位最后一个逗号并使用Substring将字符串分割:

int pos = line.LastIndexOf(',');
var elem = new XElement("shop");
elem.SetAttributeValue("name", line.Substring(0, pos).Replace(",", String.Empty));
elem.SetAttributeValue("tin", line.Substring(pos + 1));

非常好的答案,总体来说是最佳方法。我将使用我的整体解决方案编辑您的答案,因为出现了一个新的要求,我希望人们能看到它(即使通过CSV发送文件,name字段也可能包含逗号,也许应该使用更好的分隔符?) - Mike Perrenoud
@Mike:没错,你在没有加逗号的情况下连接了字符串。你可以使用“Replace”从第一个字符串中删除它们。 - Guffa
我错了!我不必修改它,因为只有两个值,并且每次都运行到最后一个位置的子字符串。非常非常非常好的解决方案,而且非常高效! - Mike Perrenoud

2
如何?
split.Take(split.Length - 1).Aggregate((s1,s2)=> s1 + s2);

或者非LINQ等价物:
string s = "";
for(int i = 0; i < split.Length - 1; i++)
{
   s += split[i];
}
return s;

1
+1 … @YoryeNathan,这是一个完全可接受的解决方案。虽然它具有二次运行时间,但对于可能的使用情况而言,这仍然可能比使用StringBuilder的解决方案更快:查看OP的代码,这用于设置名为name的XML属性值 - 你期望集合有多长? - Konrad Rudolph
2
@YoryeNathan 不,"非常慢"是指将每个结果FTP到文件服务器,然后在远程连接上将文件串联起来。使用StringBuilder略微慢一些,但在我(有偏见的)看来,"非常慢"有点言过其实。 - D Stanley
@KonradRudolph:你说得非常正确。我点赞这个答案,因为它非常正确且简洁。 - Mike Perrenoud

0
var strs = new string[100];
...

var result = strs.Aggregate(new StringBuilder(strs.Sum(x => x.Length)),
                            (sb, curr) => sb.Append(s + ", ")).ToString();

现在只需要从末尾删除最后一个", "。


StringBuilder 分配一个大小可以提高速度,但不会产生渐进速度提升。这可能比 Sum 的开销小。 - Thom Smith

0
string myString = "Hello World"
var myList= new List<int>();

for (int i = 0; i < 10; i++)
    myList.Add(i);

var newList = myList.Aggregate(string.Empty, (current, num) => current + myString.Substring(num, 1));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接