Joh*_*ley 22 language-agnostic string algorithm
将字符串列表连接到组合分隔字符串的最佳方法是什么.我主要关注何时停止添加分隔符.我将使用C#作为我的示例,但我希望这与语言无关.
编辑:我没有使用StringBuilder使代码稍微简单.
使用For循环
for(int i=0; i < list.Length; i++)
{
result += list[i];
if(i != list.Length - 1)
result += delimiter;
}
Run Code Online (Sandbox Code Playgroud)
使用For循环设置之前的第一个项目
result = list[0];
for(int i = 1; i < list.Length; i++)
result += delimiter + list[i];
Run Code Online (Sandbox Code Playgroud)
这些对于IEnumerable不起作用,因为你事先不知道列表的长度
使用foreach循环
bool first = true;
foreach(string item in list)
{
if(!first)
result += delimiter;
result += item;
first = false;
}
Run Code Online (Sandbox Code Playgroud)
foreach循环的变化
来自Jon的解决方案
StringBuilder builder = new StringBuilder();
string delimiter = "";
foreach (string item in list)
{
builder.Append(delimiter);
builder.Append(item);
delimiter = ",";
}
return builder.ToString();
Run Code Online (Sandbox Code Playgroud)
使用迭代器
再次来自乔恩
using (IEnumerator<string> iterator = list.GetEnumerator())
{
if (!iterator.MoveNext())
return "";
StringBuilder builder = new StringBuilder(iterator.Current);
while (iterator.MoveNext())
{
builder.Append(delimiter);
builder.Append(iterator.Current);
}
return builder.ToString();
}
Run Code Online (Sandbox Code Playgroud)
还有哪些其他算法?
Jon*_*eet 35
由于不同的语言和平台处理不同的字符串,并为加入字符串列表提供不同级别的内置支持,因此不可能在此提供真正的语言无关的答案.你可以在两种不同的语言中使用几乎完全相同的代码,但在一种语言中它会很棒而在另一种语言中会很糟糕.
在C#中,您可以使用:
StringBuilder builder = new StringBuilder();
string delimiter = "";
foreach (string item in list)
{
builder.Append(delimiter);
builder.Append(item);
delimiter = ",";
}
return builder.ToString();
Run Code Online (Sandbox Code Playgroud)
这将预先准备的所有逗号,但第一个项目.类似的代码在Java中也会很好.
编辑:这是一个替代方案,有点像伊恩后来的回答,但正在研究将军 IEnumerable<string>.
// Change to IEnumerator for the non-generic IEnumerable
using (IEnumerator<string> iterator = list.GetEnumerator())
{
if (!iterator.MoveNext())
{
return "";
}
StringBuilder builder = new StringBuilder(iterator.Current);
while (iterator.MoveNext())
{
builder.Append(delimiter);
builder.Append(iterator.Current);
}
return builder.ToString();
}
Run Code Online (Sandbox Code Playgroud)
在原始答案后近5年编辑...
在.NET 4中,string.Join重载非常显着.有一个超载IEnumerable<T>,自动调用ToString,并有一个过载IEnumerable<string>.因此,无论如何,您不再需要上面的代码......对于.NET.
Ian*_*son 22
在.NET中,您可以使用String.Join方法:
string concatenated = String.Join(",", list.ToArray());
Run Code Online (Sandbox Code Playgroud)
使用.NET Reflector,我们可以了解它是如何做到的:
public static unsafe string Join(string separator, string[] value, int startIndex, int count)
{
if (separator == null)
{
separator = Empty;
}
if (value == null)
{
throw new ArgumentNullException("value");
}
if (startIndex < 0)
{
throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
}
if (startIndex > (value.Length - count))
{
throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
if (count == 0)
{
return Empty;
}
int length = 0;
int num2 = (startIndex + count) - 1;
for (int i = startIndex; i <= num2; i++)
{
if (value[i] != null)
{
length += value[i].Length;
}
}
length += (count - 1) * separator.Length;
if ((length < 0) || ((length + 1) < 0))
{
throw new OutOfMemoryException();
}
if (length == 0)
{
return Empty;
}
string str = FastAllocateString(length);
fixed (char* chRef = &str.m_firstChar)
{
UnSafeCharBuffer buffer = new UnSafeCharBuffer(chRef, length);
buffer.AppendString(value[startIndex]);
for (int j = startIndex + 1; j <= num2; j++)
{
buffer.AppendString(separator);
buffer.AppendString(value[j]);
}
}
return str;
}
Run Code Online (Sandbox Code Playgroud)
当一些语言在一行中提供支持时,没有什么理由使它与语言无关,例如Python
",".join(sequence)
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅联接文档.
对于python,请确保您有一个字符串列表,否则','.join(x)将失败.对于使用2.5+的安全方法
delimiter = '","'
delimiter.join(str(a) if a else '' for a in list_object)
Run Code Online (Sandbox Code Playgroud)
"str(a)if a else''"适用于None类型,否则str()最终会生成'None',这不是很好;)