I suggest a string
extension method that copies slices between positions into a StringBuilder
and inserts the char
at each position:
public static class StringExt {
public static string InsertCharAt(this string src, char ins, IEnumerable<int> poss) {
var orderedPoss = poss.ToList();
orderedPoss.Sort();
var ans = new StringBuilder(src.Length+orderedPoss.Count);
var srcSpan = src.AsSpan();
var beginPos = 0;
foreach (var insPos in orderedPoss) {
ans.Append(srcSpan.Slice(beginPos, insPos-beginPos));
ans.Append(ins);
beginPos = insPos;
}
return ans.ToString();
}
}
NOTE: If you don't have Span
, the three argument StringBuilder.Append
method can be used instead (as @xanatos did).
PS: Per @pingfloydx33 a single allocation version using String.Create
:
public static string InsertCharAt2(this string src, char ins, IEnumerable<int> poss) {
var orderedPoss = poss.ToList();
orderedPoss.Sort();
return String.Create(src.Length + orderedPoss.Count, new { }, (ans, _) => {
var srcSpan = src.AsSpan();
var beginPos = 0;
var writePos = 0;
foreach (var insPos in orderedPoss) {
var subLen = insPos-beginPos;
srcSpan.Slice(beginPos, subLen).CopyTo(ans.Slice(writePos));
writePos += subLen;
ans[writePos++] = ins;
beginPos = insPos;
}
});