How to delete an element from an array in D
Concatenating an element x
to an array items
is eas开发者_如何学编程y in D, it's as if it were an array list:
arr ~= x;
but how do I remove an element at index i
from items
?
(Caveat: If I remove an element and then add a new element, the array must not be reallocated. So a simple slice won't work.)
Update:
Based on CyberShadow's answer about using assumeSafeAppend
, I wrote this code:
static void removeAt(T)(ref T[] arr, size_t index)
{
foreach (i, ref item; arr[index .. $ - 1])
item = arr[i + 1];
arr = arr[0 .. $ - 1];
arr.assumeSafeAppend();
}
However, the problem happens when you have something like:
auto superArr = [0, 1, 2, 3, 4]; //Must not be modified
auto arr = superArr[0 .. $ - 1];
writeln(superArr);
arr.removeAt(0); //Should copy the slice and modify the copy
writeln(superArr); //but obviously doesn't
The base array of slice should not be modified if an element is removed from the slice; instead, the slice needs to be copied.
But I have no way of knowing if an array is a slice of a bigger array... so that doesn't work.
Any suggestions?
Copying my answer on digitalmars.D (thanks for forwarding):
As has been mentioned, std.algorithm.remove can be of help. You may want to look at three of its capabilities in particular: (a) remove multiple offsets in one pass, e.g. remove(a, 0, 4) removes the first and fifth element, (b) you can remove subranges, e.g. remove(a, tuple(1, 3)) removes the second through fourth element, and (c) if you don't care about the order in which elements are left after removal you may want to look into unstable remove, which does considerably less work.
Andrei
(Caveat: If I remove an element and then add a new element, the array must not be reallocated. So a simple slice won't work.)
The assumeSafeAppend
function will tell the runtime not to reallocate the array when appending to it (i.e. it is an affirmation from the user that there aren't other slices which might be stomped by an append).
remove
from std.algorithm does an in-place remove. If you're using std.container, there's also Array.linearRemove
.
Well if order is of no importance you can copy the last element to the location of removal then reduce the array length by one.
If you just want to remove the first or last elements use slices:
array = array [1..$]
array = array [0..$-1]
Or a general way which works for a middle one as well:
array = array [0..unlucky] ~ array [unlucky+1..$]
If the elements aren't basic elements such as structs, floats, ints then arrays are implicitly arrays of pointers and this is an efficient operation.
There's no automated way of doing this, you'll have to shuffle the array items along, reset .length and then catenate.
精彩评论