Improve this page 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. Page wiki View or edit the community-maintained wiki page associated with this page.

std.array

Functions and types that manipulate built-in arrays.

License:
Boost License 1.0.

Authors:
Andrei Alexandrescu and Jonathan M Davis

Source:
std/array.d

ForeachType!Range[] array(Range)(Range r) if (isIterable!Range && !isNarrowString!Range && !isInfinite!Range);
Returns a newly-allocated dynamic array consisting of a copy of the input range, static array, dynamic array, or class or struct with an opApply function r. Note that narrow strings are handled as a special case in an overload.

Examples:
auto a = array([1, 2, 3, 4, 5][]);
assert(a == [ 1, 2, 3, 4, 5 ]);

ElementType!String[] array(String)(String str) if (isNarrowString!String);
Convert a narrow string to an array type that fully supports random access. This is handled as a special case and always returns a dchar[], const(dchar)[], or immutable(dchar)[] depending on the constness of the input.

auto assocArray(Range)(Range r) if (isInputRange!Range && isTuple!(ElementType!Range) && ElementType!Range.length == 2);
Returns a newly allocated associative array out of elements of the input range, which must be a range of tuples (Key, Value).

Examples:
auto a = assocArray(zip([0, 1, 2], ["a", "b", "c"]));
assert(is(typeof(a) == string[int]));
assert(a == [0:"a", 1:"b", 2:"c"]);

auto b = assocArray([ tuple("foo", "bar"), tuple("baz", "quux") ]);
assert(is(typeof(b) == string[string]));
assert(b == ["foo":"bar", "baz":"quux"]);

Examples:
@@@11053@@@ - Cannot be version(unittest) - recursive instantiation error
static assert(!__traits(compiles, [ tuple("foo", "bar", "baz") ].assocArray()));
static assert(!__traits(compiles, [ tuple("foo") ].assocArray()));
static assert( __traits(compiles, [ tuple("foo", "bar") ].assocArray()));

auto uninitializedArray(T, I...)(I sizes) if (allSatisfy!(isIntegral, I));
Returns a new array of type T allocated on the garbage collected heap without initializing its elements. This can be a useful optimization if every element will be immediately initialized. T may be a multidimensional array. In this case sizes may be specified for any number of dimensions from 1 to the number in T.

Examples:
double[] arr = uninitializedArray!(double[])(100);
assert(arr.length == 100);

double[][] matrix = uninitializedArray!(double[][])(42, 31);
assert(matrix.length == 42);
assert(matrix[0].length == 31);

@trusted auto minimallyInitializedArray(T, I...)(I sizes) if (allSatisfy!(isIntegral, I));
Returns a new array of type T allocated on the garbage collected heap. Initialization is guaranteed only for pointers, references and slices, for preservation of memory safety.

pure nothrow @safe bool empty(T)(in T[] a);
Implements the range interface primitive empty for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.empty is equivalent to empty(array).

Examples:
auto a = [ 1, 2, 3 ];
assert(!a.empty);
assert(a[3 .. $].empty);

pure nothrow @safe T[] save(T)(T[] a);
Implements the range interface primitive save for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.save is equivalent to save(array). The function does not duplicate the content of the array, it simply returns its argument.

Examples:
auto a = [ 1, 2, 3 ];
auto b = a.save;
assert(b is a);

pure nothrow @safe void popFront(T)(ref T[] a) if (!isNarrowString!(T[]) && !is(T[] == void[]));
Implements the range interface primitive popFront for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.popFront is equivalent to popFront(array). For narrow strings, popFront automaticaly advances to the next code point.

Examples:
auto a = [ 1, 2, 3 ];
a.popFront();
assert(a == [ 2, 3 ]);

pure nothrow @safe void popBack(T)(ref T[] a) if (!isNarrowString!(T[]) && !is(T[] == void[]));
Implements the range interface primitive popBack for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.popBack is equivalent to popBack(array). For narrow strings, popFront automaticaly eliminates the last code point.

Examples:
auto a = [ 1, 2, 3 ];
a.popBack();
assert(a == [ 1, 2 ]);

pure nothrow @safe T front(T)(T[] a) if (!isNarrowString!(T[]) && !is(T[] == void[]));
Implements the range interface primitive front for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.front is equivalent to front(array). For narrow strings, front automaticaly returns the first code point as a dchar.

Examples:
int[] a = [ 1, 2, 3 ];
assert(a.front == 1);

pure nothrow @safe T back(T)(T[] a) if (!isNarrowString!(T[]));
Implements the range interface primitive back for built-in arrays. Due to the fact that nonmember functions can be called with the first argument using the dot notation, array.back is equivalent to back(array). For narrow strings, back automaticaly returns the last code point as a dchar.

Examples:
int[] a = [ 1, 2, 3 ];
assert(a.back == 3);
a.back += 4;
assert(a.back == 7);

void insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff) if (!isSomeString!(T[]) && allSatisfy!(isInputRangeOrConvertible!T, U) && U.length > 0);
void insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff) if (isSomeString!(T[]) && allSatisfy!(isCharOrStringOrDcharRange, U));
Inserts stuff (which must be an input range or any number of implicitly convertible items) in array at position pos.

Example:
int[] a = [ 1, 2, 3, 4 ];
a.insertInPlace(2, [ 1, 2 ]);
assert(a == [ 1, 2, 1, 2, 3, 4 ]);
a.insertInPlace(3, 10u, 11);
assert(a == [ 1, 2, 1, 10, 11, 2, 3, 4]);

bool sameHead(T)(in T[] lhs, in T[] rhs);
Returns whether the fronts of lhs and rhs both refer to the same place in memory, making one of the arrays a slice of the other which starts at index 0.

bool sameTail(T)(in T[] lhs, in T[] rhs);
Returns whether the backs of lhs and rhs both refer to the same place in memory, making one of the arrays a slice of the other which end at index $.

ElementEncodingType!S[] replicate(S)(S s, size_t n) if (isDynamicArray!S);
Returns an array that consists of s (which must be an input range) repeated n times. This function allocates, fills, and returns a new array. For a lazy version, refer to std.range.repeat.

pure @safe S[] split(S)(S s) if (isSomeString!S);
Eagerly split the string s into an array of words, using whitespace as delimiter. Runs of whitespace are merged together (no empty words are produced).

@safe, pure and CTFE-able.

alias splitter = std.algorithm.splitter(Range, Separator)(Range r, Separator s) if (is(typeof(ElementType!Range.init == Separator.init)) && (hasSlicing!Range && hasLength!Range || isNarrowString!Range));
Alias for splitter">std.algorithm.splitter.

auto split(R, E)(R r, E delim) if (isForwardRange!R && is(typeof(ElementType!R.init == E.init)));
auto split(alias isTerminator, R)(R r) if (isForwardRange!R && is(typeof(unaryFun!isTerminator(r.front))));
Eagerly splits s into an array, using delim as the delimiter.

See also: std.algorithm.splitter for the lazy version of this operator.

ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, R sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) && isInputRange!R && is(Unqual!(ElementType!(ElementType!RoR)) == Unqual!(ElementType!R)));
ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror) if (isInputRange!RoR && isInputRange!(ElementType!RoR));
Concatenates all of the ranges in ror together into one array using sep as the separator if present.

Examples:
assert(join(["hello", "silly", "world"], " ") == "hello silly world");
assert(join(["hello", "silly", "world"]) == "hellosillyworld");

assert(join([[1, 2, 3], [4, 5]], [72, 73]) == [1, 2, 3, 72, 73, 4, 5]);
assert(join([[1, 2, 3], [4, 5]]) == [1, 2, 3, 4, 5]);

E[] replace(E, R1, R2)(E[] subject, R1 from, R2 to) if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 && (hasLength!R2 || isSomeString!R2));
Replace occurrences of from with to in subject. Returns a new array without changing the contents of subject, or the original array if no match is found.

void replaceInto(E, Sink, R1, R2)(Sink sink, E[] subject, R1 from, R2 to) if (isOutputRange!(Sink, E) && isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 && (hasLength!R2 || isSomeString!R2));
Same as above, but outputs the result via OutputRange sink. If no match is found the original array is transfered to sink as is.

void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff) if (isDynamicArray!Range && is(ElementEncodingType!Range : T) && !is(T == const(T)) && !is(T == immutable(T)));
Replaces elements from array with indices ranging from from (inclusive) to to (exclusive) with the range stuff. Expands or shrinks the array as needed.

Example:
int[] a = [ 1, 2, 3, 4 ];
a.replaceInPlace(1, 3, [ 9, 9, 9 ]);
assert(a == [ 1, 9, 9, 9, 4 ]);

E[] replaceFirst(E, R1, R2)(E[] subject, R1 from, R2 to) if (isDynamicArray!(E[]) && isForwardRange!R1 && is(typeof(appender!(E[])().put(from[0..1]))) && isForwardRange!R2 && is(typeof(appender!(E[])().put(to[0..1]))));
Replaces the first occurrence of from with to in a. Returns a new array without changing the contents of subject, or the original array if no match is found.

inout(T)[] replaceSlice(T)(inout(T)[] s, in T[] slice, in T[] replacement);
Returns a new array that is s with slice replaced by replacement[].

struct Appender(A : T[], T);
Implements an output range that appends data to an array. This is recommended over a ~= data when appending many elements because it is more efficient.

Example:
auto app = appender!string();
string b = "abcdefg";
foreach (char c; b) app.put(c);
assert(app.data == "abcdefg");

int[] a = [ 1, 2 ];
auto app2 = appender(a);
app2.put(3);
app2.put([ 4, 5, 6 ]);
assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);

pure nothrow @safe this(Unqual!T[] arr);
Construct an appender with a given array. Note that this does not copy the data. If the array has a larger capacity as determined by arr.capacity, it will be used by the appender. After initializing an appender on an array, appending to the original array will reallocate.

pure nothrow @safe void reserve(size_t newCapacity);
Reserve at least newCapacity elements for appending. Note that more elements may be reserved than requested. If newCapacity <= capacity, then nothing is done.

const pure nothrow @safe size_t capacity();
Returns the capacity of the array (the maximum number of elements the managed array can accommodate before triggering a reallocation). If any appending will reallocate, capacity returns 0.

inout pure nothrow @trusted inout(T)[] data();
Returns the managed array.

void put(U)(U item) if (canPutItem!U);
Appends one item to the managed array.

void put(Range)(Range items) if (canPutRange!Range);
Appends an entire range to the managed array.

void opOpAssign(string op : "~", U)(U item) if (canPutItem!U);
Appends one item to the managed array.

void opOpAssign(string op : "~", Range)(Range items) if (canPutRange!Range);
Appends an entire range to the managed array.

pure nothrow @safe void clear();
Clears the managed array. This allows the elements of the array to be reused for appending.

Note that clear is disabled for immutable or const element types, due to the possibility that Appender might overwrite immutable data.

pure @safe void shrinkTo(size_t newlength);
Shrinks the managed array to the given length.

Throws:
Exception if newlength is greater than the current array length.

struct RefAppender(A : T[], T);
An appender that can update an array in-place. It forwards all calls to an underlying appender implementation. Any calls made to the appender also update the pointer to the original array passed in.

this(T[]* arr);
Construct a ref appender with a given array reference. This does not copy the data. If the array has a larger capacity as determined by arr.capacity, it will be used by the appender. RefAppender assumes that arr is a non-null value.

Note, do not use builtin appending (i.e. ~=) on the original array passed in until you are done with the appender, because calls to the appender override those appends.

void opOpAssign(string op : "~", U)(U item) if (AppenderType.canPutItem!U);
Appends one item to the managed array.

void opOpAssign(string op : "~", Range)(Range items) if (AppenderType.canPutRange!Range);
Appends an entire range to the managed array.

const size_t capacity();
Returns the capacity of the array (the maximum number of elements the managed array can accommodate before triggering a reallocation). If any appending will reallocate, capacity returns 0.

inout inout(T)[] data();
Returns the managed array.

Appender!(E[]) appender(A : E[], E)();
Appender!(E[]) appender(A : E[], E)(A array);
Convenience function that returns an Appender!A object initialized with array.

RefAppender!(E[]) appender(A : E[]*, E)(A array);
Convenience function that returns a RefAppender!A object initialized with array. Don't use null for the array pointer, use the other version of appender instead.