Search
View source code
Display the source code in std/algorithm/mutation.d from which this page was generated on github.
Report a bug
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

# `std.algorithm.mutation.remove` - multiple declarations

## Function remove

Eliminates elements at given offsets from `range` and returns the shortened range.

``` Range remove(SwapStrategy s = SwapStrategy.stable, Range, Offset...) (   Range range,   Offset offset ) if (Offset.length >= 1 && allSatisfy!(isValidIntegralTuple, Offset)); ```

For example, here is how to remove a single element from an array:

``````string[] a = [ "a", "b", "c", "d" ];
a = a.remove(1); // remove element at offset 1
assert(a == [ "a", "c", "d"]);``````

Note that `remove` does not change the length of the original range directly; instead, it returns the shortened range. If its return value is not assigned to the original range, the original range will retain its original length, though its contents will have changed:

``````int[] a = [ 3, 5, 7, 8 ];
assert(remove(a, 1) == [ 3, 7, 8 ]);
assert(a == [ 3, 7, 8, 8 ]);``````

The element at offset `1` has been removed and the rest of the elements have shifted up to fill its place, however, the original array remains of the same length. This is because all functions in `std.algorithm` only change content, not topology. The value `8` is repeated because `move` was invoked to rearrange elements, and on integers `move` simply copies the source to the destination. To replace `a` with the effect of the removal, simply assign the slice returned by `remove` to it, as shown in the first example.

Multiple indices can be passed into `remove`. In that case, elements at the respective indices are all removed. The indices must be passed in increasing order, otherwise an exception occurs.

``````int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
assert(remove(a, 1, 3, 5) ==
[ 0, 2, 4, 6, 7, 8, 9, 10 ]);``````

(Note that all indices refer to slots in the original array, not in the array as it is being progressively shortened.)

Tuples of two integral offsets can be used to remove an indices range:

``````int[] a = [ 3, 4, 5, 6, 7];
assert(remove(a, 1, tuple(1, 3), 9) == [ 3, 6, 7 ]);``````

The tuple passes in a range closed to the left and open to the right (consistent with built-in slices), e.g. `tuple(1, 3)` means indices `1` and `2` but not `3`.

Finally, any combination of integral offsets and tuples composed of two integral offsets can be passed in:

``````int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
assert(remove(a, 1, tuple(3, 5), 9) == [ 0, 2, 5, 6, 7, 8, 10 ]);``````

In this case, the slots at positions 1, 3, 4, and 9 are removed from the array.

If the need is to remove some elements in the range but the order of the remaining elements does not have to be preserved, you may want to pass `SwapStrategy.unstable` to `remove`.

``````int[] a = [ 0, 1, 2, 3 ];
assert(remove!(SwapStrategy.unstable)(a, 1) == [ 0, 3, 2 ]);``````

In the case above, the element at slot `1` is removed, but replaced with the last element of the range. Taking advantage of the relaxation of the stability requirement, `remove` moved elements from the end of the array over the slots to be removed. This way there is less data movement to be done which improves the execution time of the function.

The function `remove` works on bidirectional ranges that have assignable lvalue elements. The moving strategy is (listed from fastest to slowest):

• If ```s == SwapStrategy.unstable && isRandomAccessRange!Range && hasLength!Range && hasLvalueElements!Range```, then elements are moved from the end of the range into the slots to be filled. In this case, the absolute minimum of moves is performed.
• Otherwise, if ```s == SwapStrategy.unstable && isBidirectionalRange!Range && hasLength!Range && hasLvalueElements!Range```, then elements are still moved from the end of the range, but time is spent on advancing between slots by repeated calls to `range.popFront`.
• Otherwise, elements are moved incrementally towards the front of `range`; a given element is never moved several times, but more elements are moved than in the previous cases.

### Parameters

NameDescription
s a SwapStrategy to determine if the original order needs to be preserved
range a bidirectional range with a length member
offset which element(s) to remove

### Returns

A range containing all of the elements of range with offset removed.

### Example

``````import std.typecons : tuple;

auto a = [ 0, 1, 2, 3, 4, 5 ];
writeln(remove!(SwapStrategy.stable)(a, 1)); // [0, 2, 3, 4, 5]
a = [ 0, 1, 2, 3, 4, 5 ];
writeln(remove!(SwapStrategy.stable)(a, 1, 3)); // [0, 2, 4, 5]
a = [ 0, 1, 2, 3, 4, 5 ];
writeln(remove!(SwapStrategy.stable)(a, 1, tuple(3, 6))); // [0, 2]

a = [ 0, 1, 2, 3, 4, 5 ];
writeln(remove!(SwapStrategy.unstable)(a, 1)); // [0, 5, 2, 3, 4]
a = [ 0, 1, 2, 3, 4, 5 ];
writeln(remove!(SwapStrategy.unstable)(a, tuple(1, 4))); // [0, 5, 4]
``````

### Example

``````import std.typecons : tuple;

// Delete an index
writeln([4, 5, 6].remove(1)); // [4, 6]

// Delete multiple indices
writeln([4, 5, 6, 7, 8].remove(1, 3)); // [4, 6, 8]

// Use an indices range
writeln([4, 5, 6, 7, 8].remove(tuple(1, 3))); // [4, 7, 8]

// Use an indices range and individual indices
writeln([4, 5, 6, 7, 8].remove(0, tuple(1, 3), 4)); // [7]
``````

### Example

`SwapStrategy.unstable` is faster, but doesn't guarantee the same order of the original array

``````writeln([5, 6, 7, 8].remove!(SwapStrategy.stable)(1)); // [5, 7, 8]
writeln([5, 6, 7, 8].remove!(SwapStrategy.unstable)(1)); // [5, 8, 7]
``````

## Function remove

Reduces the length of the bidirectional range `range` by removing elements that satisfy `pred`. If `s = SwapStrategy.unstable`, elements are moved from the right end of the range over the elements to eliminate. If `s = SwapStrategy.stable` (the default), elements are moved progressively to front such that their relative order is preserved. Returns the filtered range.

``` Range remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range) (   Range range ); ```

### Parameters

NameDescription
range a bidirectional ranges with lvalue elements or mutable character arrays

### Returns

the range with all of the elements where `pred` is `true` removed

### Example

``````static immutable base = [1, 2, 3, 2, 4, 2, 5, 2];

int[] arr = base[].dup;

// using a string-based predicate
writeln(remove!("a == 2")(arr)); // [1, 3, 4, 5]

// The original array contents have been modified,
// so we need to reset it to its original state.
// The length is unmodified however.
arr[] = base[];

// using a lambda predicate
writeln(remove!(a => a == 2)(arr)); // [1, 3, 4, 5]
``````