I'm looking for an array join that will return an array with an element inserted between consecutive elements of an input array.
string[] input = { "red", "white", "blue" };
string[] result = InterstitialJoin("or", input);
// { "red", "or", "white", "or", "blue" }
If I use string.Join
, then the output is a string, but I want the output to be an array.
Not quite what I want:
string.Join("or", input); // redorwhiteorblue
Does this already exist? Is there a more straightforward or built-in way of doing it?
I could hand-roll a function to do this, but it seems like it would require you to write all the code to create an enumerator and yield elements interleaving them with the interstitial element.
e.g.
static IEnumerable<T> InterstitialJoin<T>(T interstitial, IEnumerable<T> elements)
{
var e = elements.GetEnumerator();
if (!e.MoveNext()) yield break;
yield return e.Current;
while (e.MoveNext()) {
yield return interstitial;
yield return e.Current;
}
}
or directly with an array like this:
static T[] InterstitialArrayJoin<T>(T interstitial, T[] elements) {
T[] results = new T[elements.Length + elements.Length - 1];
int iResults = 0;
int iElements = 0;
while (iElements < elements.Length) {
if (iElements != 0) results[iResults++] = interstitial;
results[iResults++] = elements[iElements++];
}
return results;
}
1 Answer 1
Maybe this is the simplest code to insert an element between each consecutive elements of an input array using System.Linq query:
string[] input = { "red", "white", "blue" };
string[] result = input.SelectMany(x => new [] { "or", x }).Skip(1).ToArray();
// { "red", "or", "white", "or", "blue" }
Steps:
- .SelectMany(...): "Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence." - see Documentation
- .Skip(1): We have to remove first "or" delimiter, because we added it before each element and we do not want it before a first element.
- .ToArray(): Convert IEnumerable to
string[]
. If you want, you can call.ToList()
method instead to receiveList<string>
I do not know about any built-in method or a more straightforward way to achieve it.
See working example on dotnetfiddle.net
I hope it will help you.
-
1\$\begingroup\$ I love the combination of using
SelectMany
to turn one element in to multiple elements andSkip
to fix the fencepost issue. This way of thinking will serve me well in many other applications. I love how concise the code is. Much appreciated! \$\endgroup\$Wyck– Wyck2020年04月25日 15:14:45 +00:00Commented Apr 25, 2020 at 15:14