On Tuesday, 16 February 2021 at 06:03:50 UTC, H. S. Teoh wrote:
It depends on what your goal is. Do you want to permanently remove the items from the array? Or only skip over some items while iterating over it? For the latter, see std.algorithm.iteration.filter.
The array itself is read only, so it'll have to be an array of pointers/indexes.

For the former, you can use the read-head/write-head algorithm: keep two indices as you iterate over the array, say i and j: i is for reading (incremented every iteration) and j is for writing (not incremented if array[i] is to be deleted). Each iteration, if j < i, copy array[i] to array[j]. At the end of the loop, assign the value of j to the length of the array.

Example:

        int[] array = ...;
        size_t i=0, j=0;
        while (i < array.length)
        {
                doSomething(array[i]);
                if (!shouldDelete(array[i]))
                        j++;
                if (j < i)
                        array[j] = array[i];
                i++;
        }
        array.length = j;

Basically, the loop moves elements up from the back of the array on top of elements to be deleted. This is done in tandem with processing each element, so it requires only traversing array elements once, and copies array elements at most once for the entire loop. Array elements are also read / copied sequentially, to maximize CPU cache-friendliness.


T

This is most likely ideal for what i'm trying to do.(resizes/removes will probably have to propagate to other arrays) The only problem is that it does not work with the first element but i could always just handle the special case on my own.[1] I'll probably use .filter or an equivalent for an initial first pass and this algorithm for the rest, thank you both!

[1] https://run.dlang.io/is/f9p29A (the first element is still there, and the last element is missing. both occur if the first element didn't pass the check.)

Reply via email to