Array.build
Originally conceived by Dave Herman, based on: http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._build-list%29%29
Rationale
There is no easy way to create an array, of user defined length, containing values that are not undefined
. Easily build range
functionality ontop.
Prior Art
- Racket/Scheme.
(build-list n proc)
http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._build-list%29%29- Disallows missing
proc
argument
> (build-list 10 values)
'(0 1 2 3 4 5 6 7 8 9)
> (build-list 5 (lambda (x) (* x x)))
'(0 1 4 9 16)
- Ruby.
Array.new(n) {...}
http://www.ruby-doc.org/core-2.1.1/Array.html- Fills with
nil
if missingproc
argument
> Array.new(10) {|index| index}
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> Array.new(5) {|n| n * n}
=> [0, 1, 4, 9, 16]
Array.build(length, mapfn = undefined)
When the build
method is called with arguments length and optional argument mapfn the following steps are taken:
- Let len be
ToLength(length)
. - Let C be the this value.
- If
IsConstructor(C)
is true, then- Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
- Else,
- Let A be
ArrayCreate(len)
.
- Let A be
- Let k be 0.
- If mapfn is undefined, then let mapping be false.
- Else,
- If
IsCallable(_mapfn_)
is false, throw a TypeError exception. - Let mapping be true.
- If
- Repeat, while k < len
- If mapping is true, then
- Let mappedValue be the result of calling the [[Call]] internal method of mapfn with A as thisArgument and a List containing k as argumentsList.
ReturnIfAbrupt(mappedValue)
.
- Else,
- Let mappedValue be k.
- Let Pk be
ToString(k)
. - Let defineStatus be
CreateDataPropertyOrThrow(A, Pk, mappedValue)
. ReturnIfAbrupt(defineStatus)
.- Increase k by 1.
- If mapping is true, then
- Let putStatus be
Put(A, "length", len, true)
. ReturnIfAbrupt(putStatus)
.- Return A.
Examples:
> Array.build(10);
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> Array.build(5, n => n * n);
[0, 1, 4, 9, 16]
function range(lower, upper) {
return Array.build(upper - lower, n => n + lower);
}
range(9, 18);
[9, 10, 11, 12, 13, 14, 15, 16, 17];
Could we re-propose it to ECMA-proposals? since it makes things really simpler