With results
0,1,2,3,4,5,6,7,8,9,10
0,8,9,5,6,7,1,2,3,4,10
I have the following code:
internal class Program
{
static void Main(string[] args)
{
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Console.WriteLine(string.Join(",", array));
SwapElements(ref array, 1..5, 8..10);
Console.WriteLine(string.Join(",", array));
}
static void SwapElements<T>(ref T[] array, Range a, Range b)
{
(int a_Offset, int a_Length) = a.GetOffsetAndLength(array.Length);
(int b_Offset, int b_Length) = b.GetOffsetAndLength(array.Length);
if (a_Offset > b_Offset)
{
((b_Offset, b_Length), (a_Offset, a_Length)) = ((a_Offset, a_Length), (b_Offset, b_Length));
}
Range pre_a = Range.EndAt(a_Offset);
a = new Range(a_Offset, a_Offset + a_Length);
Range between = new Range(a_Offset + a_Length, b_Offset);
b = new Range(b_Offset, b_Offset + b_Length);
Range post_b = Range.StartAt(b_Offset + b_Length);
array = Concat(array[pre_a], array[b], array[between], array[a], array[post_b]);
}
/// <summary>
/// Concatenates two or more arrays into a single one.
/// </summary>
/// <remarks>
/// Code taken from https://stackoverflow.com/a/52749536/380384
/// </remarks>
public static T[] Concat<T>(params T[][] arrays)
{
// return (from array in arrays from arr in array select arr).ToArray();
var result = new T[arrays.Sum(a => a.Length)];
int offset = 0;
for (int x = 0; x < arrays.Length; x++)
{
arrays[x].CopyTo(result, offset);
offset += arrays[x].Length;
}
return result;
}
}
Notes.
I am using Range
objects to define the array slices to be swapped. I use a custom Concat
function stolen from [SO] to re-assemble the array from the different slices. An ordering of the slices is done before the operation to ensure the elements between the two slices are defined properly.
C# Ranges use some obscure notion defining a range from start
to end
as start..(end+1)
for some reason. 70 years ago Fortran did the same with start:end
that made sense, and every other vector language since (like Matlab etc), yet when C# introduced slices, they completely foobar'd in order to make it Python-like for no good reason. End of rant.