| Function Name | Description |
|---|---|
| array | Returns a copy of the input in a newly allocated dynamic array. |
| appender | Returns a newAppender orRefAppender initialized with a given array. |
| assocArray | Returns a newly allocated associative array from a range of key/value tuples. |
| byPair | Construct a range iterating over an associative array by key/value tuples. |
| insertInPlace | Inserts into an existing array at a given position. |
| join | Concatenates a range of ranges into one array. |
| minimallyInitializedArray | Returns a new array of typeT. |
| replace | Returns a new array with all occurrences of a certain subrange replaced. |
| replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. |
| replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. |
| replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. |
| replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. |
| replaceSlice | Returns a new array with a given slice replaced. |
| replicate | Creates a new array out of several copies of an input array or range. |
| sameHead | Checks if the initial segments of two arrays refer to the same place in memory. |
| sameTail | Checks if the final segments of two arrays refer to the same place in memory. |
| split | Eagerly split a range or string into an array. |
| staticArray | Creates a new static array from given data. |
| uninitializedArray | Returns a new array of typeT without initializing its elements. |
Sourcestd/array.d
array(Range)(Ranger)array(Range)(Ranger)r.Ranger | range (or aggregate withopApply function) whose elements are copied into the allocated array |
auto a =array([1, 2, 3, 4, 5][]);writeln(a);// [1, 2, 3, 4, 5]
array(String)(scope Stringstr)NOTEThis function is never used when autodecoding is turned off.
Stringstr | isNarrowString to be converted to an array ofdchar |
import std.range.primitives : isRandomAccessRange;import std.traits : isAutodecodableString;// note that if autodecoding is turned off, `array` will not transcode these.staticif (isAutodecodableString!string) writeln("Hello D".array);// "Hello D"delse writeln("Hello D".array);// "Hello D"staticif (isAutodecodableString!wstring) writeln("Hello D"w.array);// "Hello D"delse writeln("Hello D"w.array);// "Hello D"wstaticassert(isRandomAccessRange!dstring ==true);
assocArray(Range)(Ranger)assocArray(Keys, Values)(Keyskeys, Valuesvalues)Ranger | Aninput range of tuples of keys and values. |
Keyskeys | Aninput range of keys |
Valuesvalues | Aninput range of values |
DuplicatesAssociative arrays have unique keys. If r contains duplicate keys, then the result will contain the value of the last pair for that key in r.
import std.range : repeat, zip;import std.typecons : tuple;import std.range.primitives : autodecodeStrings;auto a =assocArray(zip([0, 1, 2], ["a","b","c"]));// aka zipMapstaticassert(is(typeof(a) == string[int]));writeln(a);// [0:"a", 1:"b", 2:"c"]auto b =assocArray([ tuple("foo","bar"), tuple("baz","quux") ]);staticassert(is(typeof(b) == string[string]));writeln(b);// ["foo":"bar", "baz":"quux"]staticif (autodecodeStrings)alias achar =dchar;elsealias achar =immutable(char);auto c =assocArray("ABCD",true.repeat);staticassert(is(typeof(c) ==bool[achar]));bool[achar] expected = ['D':true, 'A':true, 'B':true, 'C':true];writeln(c);// expected
byPair(AA)(AAaa)AAaa | The associative array to iterate over. |
import std.algorithm.sorting : sort;import std.typecons : tuple, Tuple;autoaa = ["a": 1,"b": 2,"c": 3];Tuple!(string,int)[] pairs;// Iteration over key/value pairs.foreach (pair;aa.byPair){if (pair.key =="b") pairs ~= tuple("B", pair.value);else pairs ~= pair;}// Iteration order is implementation-dependent, so we should sort it to get// a fixed order.pairs.sort();assert(pairs == [ tuple("B", 2), tuple("a", 1), tuple("c", 3)]);
uninitializedArray(T, I...)(Isizes)uninitializedArray(T, I...)(Isizes)| T | The type of the resulting array elements |
Isizes | The length dimension(s) of the resulting array |
double[] arr =uninitializedArray!(double[])(100);writeln(arr.length);// 100double[][] matrix =uninitializedArray!(double[][])(42, 31);writeln(matrix.length);// 42writeln(matrix[0].length);// 31char*[] ptrs =uninitializedArray!(char*[])(100);writeln(ptrs.length);// 100
minimallyInitializedArray(T, I...)(Isizes)| T | The type of the array elements |
Isizes | The length dimension(s) of the resulting array |
import std.algorithm.comparison : equal;import std.range : repeat;auto arr =minimallyInitializedArray!(int[])(42);writeln(arr.length);// 42// Elements aren't necessarily initialized to 0, so don't do this:// assert(arr.equal(0.repeat(42)));// If that is needed, initialize the array normally instead:auto arr2 =newint[42];assert(arr2.equal(0.repeat(42)));
overlap(T, U)(T[]a, U[]b)a.ptr <b.ptr) == bool));overlap only compares the pointers and lengths in theranges, not the values referred by them. Ifr1 andr2 have anoverlapping slice, returns that slice. Otherwise, returns the nullslice.T[]a | The first array to compare |
U[]b | The second array to compare |
int[]a = [ 10, 11, 12, 13, 14 ];int[]b =a[1 .. 3];writeln(overlap(a,b));// [11, 12]b =b.dup;// overlap disappears even though the content is the sameassert(overlap(a,b).empty);static test()() @nogc{autoa ="It's three o'clock"d;autob =a[5 .. 10];returnb.overlap(a);}//works at compile-timestaticassert(test =="three"d);
import std.meta : AliasSeq;// can be used as an alternative implementation of overlap that returns// `true` or `false` instead of a slice of the overlapbool isSliceOf(T)(constscope T[] part,constscope T[] whole){return part.overlap(whole)is part;}auto x = [1, 2, 3, 4, 5];assert(isSliceOf(x[3..$], x));assert(isSliceOf(x[], x));assert(!isSliceOf(x, x[3..$]));assert(!isSliceOf([7, 8], x));assert(isSliceOf(null, x));// null is a slice of itselfassert(isSliceOf(null,null));foreach (T; AliasSeq!(int[],const(int)[],immutable(int)[],constint[],immutableint[])){ Ta = [1, 2, 3, 4, 5]; Tb =a; T c =a[1 .. $]; T d =a[0 .. 1]; T e =null;assert(isSliceOf(a,a));assert(isSliceOf(b,a));assert(isSliceOf(a,b));assert(isSliceOf(c,a));assert(isSliceOf(c,b));assert(!isSliceOf(a, c));assert(!isSliceOf(b, c));assert(isSliceOf(d,a));assert(isSliceOf(d,b));assert(!isSliceOf(a, d));assert(!isSliceOf(b, d));assert(isSliceOf(e,a));assert(isSliceOf(e,b));assert(isSliceOf(e, c));assert(isSliceOf(e, d));//verifies R-value compatibiltyassert(!isSliceOf(a[$ .. $],a));assert(isSliceOf(a[0 .. 0],a));assert(isSliceOf(a,a[0.. $]));assert(isSliceOf(a[0 .. $],a));}
insertInPlace(T, U...)(ref T[]array, size_tpos, Ustuff)insertInPlace(T, U...)(ref T[]array, size_tpos, Ustuff)stuff (which must be an input range or any number of implicitly convertible items) inarray at positionpos.T[]array | The array thatstuff will be inserted into. |
size_tpos | The position inarray to insert thestuff. |
Ustuff | Aninput range, or any number of implicitly convertible items to insert intoarray. |
int[] a = [ 1, 2, 3, 4 ];a.insertInPlace(2, [ 1, 2 ]);writeln(a);// [1, 2, 1, 2, 3, 4]a.insertInPlace(3, 10u, 11);writeln(a);// [1, 2, 1, 10, 11, 2, 3, 4]union U{float a = 3.0;int b;}U u1 = { b : 3 };U u2 = { b : 4 };U u3 = { b : 5 };U[] unionArr = [u2, u3];unionArr.insertInPlace(2, [u1]);writeln(unionArr);// [u2, u3, u1]unionArr.insertInPlace(0, [u3, u2]);writeln(unionArr);// [u3, u2, u2, u3, u1]staticclass C{int a;float b;this(int a,float b) {this.a = a;this.b = b; }}C c1 =new C(42, 1.0);C c2 =new C(0, 0.0);C c3 =new C(int.max,float.init);C[] classArr = [c1, c2, c3];insertInPlace(classArr, 3, [c2, c3]);C[5] classArr1 = classArr;writeln(classArr1);// [c1, c2, c3, c2, c3]insertInPlace(classArr, 0, c3, c1);C[7] classArr2 = classArr;writeln(classArr2);// [c3, c1, c1, c2, c3, c2, c3]
sameHead(T)(in T[]lhs, in T[]rhs);lhs andrhs both refer to the same place in memory, making one of the arrays a slice of the other which starts at index0.T[]lhs | the first array to compare |
T[]rhs | the second array to compare |
auto a = [1, 2, 3, 4, 5];auto b = a[0 .. 2];assert(a.sameHead(b));
sameTail(T)(in T[]lhs, in T[]rhs);lhs andrhs both refer to the same place in memory, making one of the arrays a slice of the other which end at index$.T[]lhs | the first array to compare |
T[]rhs | the second array to compare |
auto a = [1, 2, 3, 4, 5];auto b = a[3..$];assert(a.sameTail(b));
replicate(S)(Ss, size_tn)replicate(S)(Ss, size_tn)Ss | aninput range or a dynamic array |
size_tn | number of times to repeats |
s repeatedn times. This function allocates, fills, and returns a new array.auto a ="abc";autos =replicate(a, 3);writeln(s);// "abcabcabc"auto b = [1, 2, 3];auto c =replicate(b, 3);writeln(c);// [1, 2, 3, 1, 2, 3, 1, 2, 3]auto d =replicate(b, 0);writeln(d);// []
split(S)(Ss)split(Range, Separator)(Rangerange, Separatorsep)split(alias isTerminator, Range)(Rangerange)range.front))));range into an array, usingsep as the delimiter.range must be aforward range.The separator can be a value of the same type as the elements inrangeor it can be another forwardrange.Ss | the string to split by word if no separator is given |
Rangerange | the range to split |
Separatorsep | a value of the same type as the elements ofrange or another |
| isTerminator | a predicate that splits the range when it returnstrue. |
range (or the words ofs).import std.uni : isWhite;writeln("Learning,D,is,fun".split(","));// ["Learning", "D", "is", "fun"]writeln("Learning D is fun".split!isWhite);// ["Learning", "D", "is", "fun"]writeln("Learning D is fun".split(" D "));// ["Learning", "is fun"]
string str ="Hello World!";writeln(str.split);// ["Hello", "World!"]string str2 ="Hello\t\tWorld\t!";writeln(str2.split);// ["Hello", "World", "!"]
writeln(split("hello world"));// ["hello", "world"]writeln(split("192.168.0.1","."));// ["192", "168", "0", "1"]auto a =split([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], [2, 3]);writeln(a);// [[1], [4, 5, 1], [4, 5]]
join(RoR, R)(RoRror, Rsep)join(RoR, E)(RoRror, scope Esep)join(RoR)(RoRror)ror together (with the GC) into one array usingsep as the separator if present.RoRror | Aninput range of input ranges |
Rsep | An input range, or a single element, to join the ranges on |
writeln(join(["hello","silly","world"]," "));// "hello silly world"writeln(join(["hello","silly","world"]));// "hellosillyworld"writeln(join([[1, 2, 3], [4, 5]], [72, 73]));// [1, 2, 3, 72, 73, 4, 5]writeln(join([[1, 2, 3], [4, 5]]));// [1, 2, 3, 4, 5]const string[] arr = ["apple","banana"];writeln(arr.join(","));// "apple,banana"writeln(arr.join());// "applebanana"
replace(E, R1, R2)(E[]subject, R1from, R2to)from withto insubject in a new array.E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replace all instances offrom with |
subject, or the original array if no match is found.writeln("Hello Wörld".replace("o Wö","o Wo"));// "Hello World"writeln("Hello Wörld".replace("l","h"));// "Hehho Wörhd"
replace(E, R1, R2)(E[]subject, R1from, R2to, ref size_tchanged)from withto insubject in a new array.changed counts how many replacements took place.E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replace all instances offrom with |
size_tchanged | the number of replacements |
subject, or the original array if no match is found.size_tchanged = 0;writeln("Hello Wörld".replace("o Wö","o Wo",changed));// "Hello World"writeln(changed);// 1changed = 0;writeln("Hello Wörld".replace("l","h",changed));// "Hehho Wörhd"import std.stdio : writeln;writeln(changed);writeln(changed);// 3
replaceInto(E, Sink, R1, R2)(Sinksink, E[]subject, R1from, R2to)from withto insubject and output the result intosink.Sinksink | anoutput range |
E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replace all instances offrom with |
auto arr = [1, 2, 3, 4, 5];autofrom = [2, 3];autoto = [4, 6];autosink = appender!(int[])();replaceInto(sink, arr,from,to);writeln(sink.data);// [1, 4, 6, 4, 5]
replaceInto(E, Sink, R1, R2)(Sinksink, E[]subject, R1from, R2to, ref size_tchanged)from withto insubject and output the result intosink.changed counts how many replacements took place.Sinksink | anoutput range |
E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replace all instances offrom with |
size_tchanged | the number of replacements |
auto arr = [1, 2, 3, 4, 5];autofrom = [2, 3];autoto = [4, 6];autosink = appender!(int[])();size_tchanged = 0;replaceInto(sink, arr,from,to,changed);writeln(sink.data);// [1, 4, 6, 4, 5]writeln(changed);// 1
replace(T, Range)(T[]subject, size_tfrom, size_tto, Rangestuff)from (inclusive) toto (exclusive) with the rangestuff.T[]subject | the array to scan |
size_tfrom | the starting index |
size_tto | the ending index |
Rangestuff | the items to replace in-betweenfrom andto |
subject.auto a = [ 1, 2, 3, 4 ];auto b = a.replace(1, 3, [ 9, 9, 9 ]);writeln(a);// [1, 2, 3, 4]writeln(b);// [1, 9, 9, 9, 4]
replaceInPlace(T, Range)(ref T[]array, size_tfrom, size_tto, Rangestuff)array,from,to,stuff))));array with indices ranging fromfrom (inclusive) toto (exclusive) with the rangestuff. Expands or shrinks the array as needed.T[]array | the array to scan |
size_tfrom | the starting index |
size_tto | the ending index |
Rangestuff | the items to replace in-betweenfrom andto |
int[] a = [1, 4, 5];replaceInPlace(a, 1u, 2u, [2, 3, 4]);writeln(a);// [1, 2, 3, 4, 5]replaceInPlace(a, 1u, 2u,cast(int[])[]);writeln(a);// [1, 3, 4, 5]replaceInPlace(a, 1u, 3u, a[2 .. 4]);writeln(a);// [1, 4, 5, 5]
replaceFirst(E, R1, R2)(E[]subject, R1from, R2to)from[0..1]))) && isForwardRange!R2 && is(typeof(appender!(E[])().put(to[0..1]))));from withto insubject.E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replacefrom with |
subject, or the original array if no match is found.auto a = [1, 2, 2, 3, 4, 5];auto b = a.replaceFirst([2], [1337]);writeln(b);// [1, 1337, 2, 3, 4, 5]auto s ="This is a foo foo list";auto r = s.replaceFirst("foo","silly");writeln(r);// "This is a silly foo list"
replaceLast(E, R1, R2)(E[]subject, R1from, R2to)from[0..1]))) && isForwardRange!R2 && is(typeof(appender!(E[])().put(to[0..1]))));from withto insubject.E[]subject | the array to scan |
R1from | the item to replace |
R2to | the item to replacefrom with |
subject, or the original array if no match is found.auto a = [1, 2, 2, 3, 4, 5];auto b = a.replaceLast([2], [1337]);writeln(b);// [1, 2, 1337, 3, 4, 5]auto s ="This is a foo foo list";auto r = s.replaceLast("foo","silly");writeln(r);// "This is a foo silly list"
replaceSlice(T)(inout(T)[]s, in T[]slice, in T[]replacement);slice are replaced with the items inreplacement.slice andreplacement do not need to be the same length. The result will grow or shrink based on the items given.inout(T)[]s | the base of the new array |
T[]slice | the slice ofs to be replaced |
T[]replacement | the items to replaceslice with |
s withslice replaced byreplacement[].auto a = [1, 2, 3, 4, 5];auto b =replaceSlice(a, a[1 .. 4], [0, 0, 0]);writeln(b);// [1, 0, 0, 0, 5]
Appender(A) if (isDynamicArray!A);Appender maintains its own array metadata locally, so it can avoidtheperformance hit of looking up slicecapacityfor each append.| A | the array type to simulate. |
auto app = appender!string();string b ="abcdefg";foreach (char c; b) app.put(c);writeln(app[]);// "abcdefg"int[] a = [ 1, 2 ];auto app2 = appender(a);app2.put(3);writeln(app2.length);// 3app2.put([ 4, 5, 6 ]);writeln(app2[]);// [1, 2, 3, 4, 5, 6]
arr);arr.capacity, it will be used by the appender. After initializing an appender on an array, appending to the original array will reallocate.reserve(size_tnewCapacity);newCapacity <= capacity, then nothing is done.size_tnewCapacity | the capacity theAppender should have |
capacity() const;length() const;data() inout;opSlice() inout;put(U)(Uitem)item to the managed array. Performs encoding forchar types ifA is a differently typedchar array.Uitem | the single item to append |
put(Range)(Rangeitems)Rangeitems | the range of items to append |
opOpAssign(string op : "~")clear();Noteclear is disabled for immutable or const element types, due to the possibility thatAppender might overwrite immutable data.
shrinkTo(size_tnewlength);NoteshrinkTo is disabled for immutable or const element types.
toString()() const;toString(Writer)(ref Writerw, ref scope const FormatSpec!charfmt) constWriterw | Achar acceptingoutput range. |
FormatSpec!charfmt | Astd.format.FormatSpec which controls how the array is formatted. |
RefAppender(A) if (isDynamicArray!A);TipUse thearrayPtr overload ofappender for construction with type-inference.
| A | The array type to simulate |
int[] a = [1, 2];auto app2 = appender(&a);writeln(app2[]);// [1, 2]writeln(a);// [1, 2]app2 ~= 3;writeln(app2.length);// 3app2 ~= [4, 5, 6];writeln(app2[]);// [1, 2, 3, 4, 5, 6]writeln(a);// [1, 2, 3, 4, 5, 6]app2.reserve(5);assert(app2.capacity >= 5);
arr);arr.capacity, it will be used by the appender.NoteDo not use built-in appending (i.e.~=) on the original array until you are done with the appender, because subsequent calls to the appender will reallocate the array data without those appends.
A*arr | Pointer to an array. Must not be null. |
opDispatch(string fn, Args...)(Argsargs)args)")));| fn | Method name to call. |
Argsargs | Arguments to pass to the method. |
opOpAssign(string op : "~", U)(Urhs)rhs);}));rhs to the managed array.Urhs | Element or range. |
capacity() const;capacity returns0.length() const;opSlice() inout;appender(A)()appender(A : E[], E)(auto ref Aarray);array.auto w =appender!string;// pre-allocate space for at least 10 elements (this avoids costly reallocations)w.reserve(10);assert(w.capacity >= 10);w.put('a');// single elementsw.put("bc");// multiple elements// use the append syntaxw ~= 'd';w ~="ef";writeln(w[]);// "abcdef"
appender(P : E[]*, E)(ParrayPtr);arrayPtr. Don't use null for the array pointer, use the other version ofappender instead.int[] a = [1, 2];auto app2 =appender(&a);writeln(app2[]);// [1, 2]writeln(a);// [1, 2]app2 ~= 3;app2 ~= [4, 5, 6];writeln(app2[]);// [1, 2, 3, 4, 5, 6]writeln(a);// [1, 2, 3, 4, 5, 6]app2.reserve(5);assert(app2.capacity >= 5);
staticArray(T, size_t n)(auto ref T[n]a);staticArray(U, T, size_t n)(auto ref T[n]a)NotestaticArray returns by value, so expressions involving large arrays may be inefficient.
T[n]a | The input array. |
a.autoa = [0, 1].staticArray;staticassert(is(typeof(a) ==int[2]));writeln(a);// [0, 1]
auto b = [0, 1].staticArray!long;staticassert(is(typeof(b) ==long[2]));writeln(b);// [0, 1]
staticArray(size_t n, T)(scope Ta)staticArray(size_t n, T)(scope Ta, out size_trangeLength)staticArray(Un : U[n], U, size_t n, T)(scope Ta)staticArray(Un : U[n], U, size_t n, T)(scope Ta, out size_trangeLength)staticArray(alias a)()staticArray(U, alias a)()a.length is not known at compile time, the number of elements must begiven as a template argument (e.g.myrange.staticArray!2).Size and type can be combined, if the source range elements are implicitlyconvertible to the requested element type (eg:2.iota.staticArray!(long[2])).a is known at compile time, it can be given as atemplate argument to avoid having to specify the number of elements(e.g.:staticArray!(2.iota) orstaticArray!(double, 2.iota)).Ta | The input range. If there are less elements than the specified length of the static array, the rest of it is default-initialized. If there are more than specified, the first elements up to the specified length are used. |
size_trangeLength | Output for the number of elements used froma. Optional. |
import std.range : iota;auto input = 3.iota;autoa = input.staticArray!2;staticassert(is(typeof(a) ==int[2]));writeln(a);// [0, 1]auto b = input.staticArray!(long[4]);staticassert(is(typeof(b) ==long[4]));writeln(b);// [0, 1, 2, 0]
import std.range : iota;enuma =staticArray!(2.iota);staticassert(is(typeof(a) ==int[2]));writeln(a);// [0, 1]enum b =staticArray!(long, 2.iota);staticassert(is(typeof(b) ==long[2]));writeln(b);// [0, 1]