patterncsharpMinor
"Breaking out" elements from an array
Viewed 0 times
elementsarraybreakingfromout
Problem
I wrote a method that takes an array
I am assuming that all the
Furthermore, I wonder if this way is faster than an if statement that is contained within a
T[] array (T is a type parameter) and a second array int[] indices. The method should remove those entries from array, whose indices are stored in indices. Then, the resulting array will be "returned" as an out-parameter T[] rest. Finally, there is a second out parameter T[] removed that contains the removed items.public static void RemoveViaIndex(this T[] array, int[] indices, out T[] rest, out T[] removed)
{
int arrayLength = array.Length;
int indicesLength = indices.Length;
if (indicesLength == 0 || arrayLength == 0)
{
rest = array;
removed = new T[0];
return;
}
rest = new T[arrayLength - indicesLength];
removed = new T[indicesLength];
int copyBegin = 0;
int copyEnd = -1;
// We will only iterate over the index-array once
// Therefore, the indices have to be in ascending order
Array.Sort(indices);
for (int indexForIndices = 0; indexForIndices < indicesLength; indexForIndices++)
{
// Copying elements in a chunk that ends at the
// next index that has to be removed
copyEnd = indices[indexForIndices];
Array.Copy(sourceArray: array, sourceIndex: copyBegin,
destinationArray: rest, destinationIndex: copyBegin - indexForIndices,
length: copyEnd - copyBegin);
removed[indexForIndices] = array[copyEnd];
copyBegin = copyEnd + 1;
}
if (copyEnd < arrayLength - 1)
{
// Copy the final chunk that the loop did not take (if there is one)
Array.Copy(array, copyBegin, rest, copyEnd - indicesLength + 1, arrayLength - copyBegin);
}
}I am assuming that all the
indices in same-named array are valid indices for array. Are there any further border cases that I did not cover?Furthermore, I wonder if this way is faster than an if statement that is contained within a
for loop that iterates over the source array since the if-currentIndSolution
So far my tests indicate that the performance is slightly better in the larger test cases because there is no hashing involved when accessing elements in
deleteStatusArray. There are also no array copy operations.public static void ZRemoveIndex(this T[] array, int[] indices, out T[] rest, out T[] removed)
{
int arrayLength = array.Length;
int indicesLength = indices.Length;
if (indicesLength == 0 || arrayLength == 0)
{
rest = array;
removed = new T[0];
return;
}
rest = new T[arrayLength - indicesLength];
removed = new T[indicesLength];
//memo to remember which array indices are removed
//all elements will be false by default
var deleteStatusArray = new bool[array.Length];
foreach (var removeIndex in indices)
{
//mark index that should be considered deleted
deleteStatusArray[removeIndex] = true;
}
var notRemovedCounter = 0;
var removedCounter = 0;
for (int i = 0; i < array.Length; i++)
{
if(!deleteStatusArray[i])
rest[notRemovedCounter++]= array[i];
else
removed[removedCounter++] = array[i];
}
}Code Snippets
public static void ZRemoveIndex<T>(this T[] array, int[] indices, out T[] rest, out T[] removed)
{
int arrayLength = array.Length;
int indicesLength = indices.Length;
if (indicesLength == 0 || arrayLength == 0)
{
rest = array;
removed = new T[0];
return;
}
rest = new T[arrayLength - indicesLength];
removed = new T[indicesLength];
//memo to remember which array indices are removed
//all elements will be false by default
var deleteStatusArray = new bool[array.Length];
foreach (var removeIndex in indices)
{
//mark index that should be considered deleted
deleteStatusArray[removeIndex] = true;
}
var notRemovedCounter = 0;
var removedCounter = 0;
for (int i = 0; i < array.Length; i++)
{
if(!deleteStatusArray[i])
rest[notRemovedCounter++]= array[i];
else
removed[removedCounter++] = array[i];
}
}Context
StackExchange Code Review Q#104938, answer score: 3
Revisions (0)
No revisions yet.