On Monday, 30 January 2017 at 10:30:22 UTC, cym13 wrote:
On Monday, 30 January 2017 at 08:50:14 UTC, albert-j wrote:
On Monday, 30 January 2017 at 00:17:51 UTC, ag0aep6g wrote:
Removing works by overwriting the array with only the wanted
values and discarding the rest.
But then why do I get this:
import std.stdio, std.algorithm, std.array;
int[] arr;
foreach (i; 0..10) arr ~= i; // [0, 1, 2, 3, 4, 5, 6, 7,
8, 9]
writeln("&arr[0]:", &arr[0]); // prints "7F56FAE93000"
arr = arr.remove!(x => x > 5).array;
writeln("&arr[0]:", &arr[0]); // prints "7F56FAE92020"
writeln("arr:",arr); // prints: "[0, 1, 2, 3, 4, 5]"
It looks like arr.remove allocates new memory and copies the
data there.
No, remove works in-place, you are the one specifically asking
for a reallocation here: instead of
arr = arr.remove!(x => x>5).array;
write
arr.remove!(x => x>5);
Complete example:
import std.stdio;
import std.format;
import std.algorithm;
void main(string[] args) {
int [] arr = [0, 1, 2, 3, 4, 5];
auto before = arr.ptr;
arr.remove!(x => x>5);
auto after = arr.ptr;
assert(before == after, "%s %s".format(before, after));
}
Meh.
Forget that, bad memory. remove isn't working in-place. However
slapping ".array" is still asking explicitely for reallocation,
so just forget it. Here is a code that works:
import std.conv;
import std.stdio;
import std.format;
import std.algorithm;
void main(string[] args) {
int [] arr = [8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
auto before = arr.ptr;
arr = arr.remove!(x => x>5);
auto after = arr.ptr;
assert(arr == [0, 1, 2, 3, 4, 5], arr.to!string);
assert(before == after, "%s %s".format(before, after));
}