Implement array.flat and array.flatMap
parent
8ac840e319
commit
7fd9c4b7e3
|
@ -1073,6 +1073,114 @@ function ArrayConcat(arg1) {
|
|||
return A;
|
||||
}
|
||||
|
||||
// https://tc39.github.io/proposal-flatMap/
|
||||
// January 4, 2019
|
||||
function ArrayFlatMap(mapperFunction/*, thisArg*/) {
|
||||
// Step 1.
|
||||
var O = ToObject(this);
|
||||
|
||||
// Step 2.
|
||||
var sourceLen = ToLength(O.length);
|
||||
|
||||
// Step 3.
|
||||
if (!IsCallable(mapperFunction))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction));
|
||||
|
||||
// Step 4.
|
||||
var T = arguments.length > 1 ? arguments[1] : undefined;
|
||||
|
||||
// Step 5.
|
||||
var A = ArraySpeciesCreate(O, 0);
|
||||
|
||||
// Step 6.
|
||||
FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T);
|
||||
|
||||
// Step 7.
|
||||
return A;
|
||||
}
|
||||
|
||||
// https://tc39.github.io/proposal-flatMap/
|
||||
// January 4, 2019
|
||||
function ArrayFlat(/* depth */) {
|
||||
// Step 1.
|
||||
var O = ToObject(this);
|
||||
|
||||
// Step 2.
|
||||
var sourceLen = ToLength(O.length);
|
||||
|
||||
// Step 3.
|
||||
var depthNum = 1;
|
||||
|
||||
// Step 4.
|
||||
if (arguments.length > 0 && arguments[0] !== undefined)
|
||||
depthNum = ToInteger(arguments[0]);
|
||||
|
||||
// Step 5.
|
||||
var A = ArraySpeciesCreate(O, 0);
|
||||
|
||||
// Step 6.
|
||||
FlattenIntoArray(A, O, sourceLen, 0, depthNum);
|
||||
|
||||
// Step 7.
|
||||
return A;
|
||||
}
|
||||
|
||||
// https://tc39.github.io/proposal-flatMap/
|
||||
// January 4, 2019
|
||||
function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunction, thisArg) {
|
||||
// Step 1.
|
||||
var targetIndex = start;
|
||||
|
||||
// Steps 2-3.
|
||||
for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) {
|
||||
// Steps 3.a-c.
|
||||
if (sourceIndex in source) {
|
||||
// Step 3.c.i.
|
||||
var element = source[sourceIndex];
|
||||
|
||||
if (mapperFunction) {
|
||||
// Step 3.c.ii.1.
|
||||
assert(arguments.length === 7, "thisArg is present");
|
||||
|
||||
// Step 3.c.ii.2.
|
||||
element = callContentFunction(mapperFunction, thisArg, element, sourceIndex, source);
|
||||
}
|
||||
|
||||
// Step 3.c.iii.
|
||||
var shouldFlatten = false;
|
||||
|
||||
// Step 3.c.iv.
|
||||
if (depth > 0) {
|
||||
// Step 3.c.iv.1.
|
||||
shouldFlatten = IsArray(element);
|
||||
}
|
||||
|
||||
// Step 3.c.v.
|
||||
if (shouldFlatten) {
|
||||
// Step 3.c.v.1.
|
||||
var elementLen = ToLength(element.length);
|
||||
|
||||
// Step 3.c.v.2.
|
||||
// Recursive call to walk the depth.
|
||||
targetIndex = FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1);
|
||||
} else {
|
||||
// Step 3.c.vi.1.
|
||||
if (targetIndex >= MAX_NUMERIC_INDEX)
|
||||
ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
|
||||
|
||||
// Step 3.c.vi.2.
|
||||
_DefineDataProperty(target, targetIndex, element);
|
||||
|
||||
// Step 3.c.vi.3.
|
||||
targetIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
return targetIndex;
|
||||
}
|
||||
|
||||
function ArrayStaticConcat(arr, arg1) {
|
||||
if (arguments.length < 1)
|
||||
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat');
|
||||
|
|
|
@ -3169,6 +3169,11 @@ static const JSFunctionSpec array_methods[] = {
|
|||
|
||||
/* ES7 additions */
|
||||
JS_SELF_HOSTED_FN("includes", "ArrayIncludes", 2,0),
|
||||
|
||||
/* ES2019 additions */
|
||||
JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0),
|
||||
JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0),
|
||||
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
@ -3333,6 +3338,8 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
|
|||
!DefineProperty(cx, unscopables, cx->names().fill, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().find, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().findIndex, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().flat, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().flatMap, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().includes, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().keys, value) ||
|
||||
!DefineProperty(cx, unscopables, cx->names().values, value))
|
||||
|
|
|
@ -26,6 +26,8 @@ assertDeepEq(keys, [
|
|||
"fill",
|
||||
"find",
|
||||
"findIndex",
|
||||
"flat",
|
||||
"flatMap",
|
||||
"includes",
|
||||
"keys",
|
||||
"values"
|
||||
|
|
|
@ -115,6 +115,8 @@
|
|||
macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \
|
||||
macro(fix, fix, "fix") \
|
||||
macro(flags, flags, "flags") \
|
||||
macro(flat, flat, "flat") \
|
||||
macro(flatMap, flatMap, "flatMap") \
|
||||
macro(float32, float32, "float32") \
|
||||
macro(Float32x4, Float32x4, "Float32x4") \
|
||||
macro(float64, float64, "float64") \
|
||||
|
|
|
@ -198,7 +198,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
|||
"pop", "shift", "unshift", "splice", "concat", "slice", "lastIndexOf", "indexOf",
|
||||
"includes", "forEach", "map", "reduce", "reduceRight", "filter", "some", "every", "find",
|
||||
"findIndex", "copyWithin", "fill", Symbol.iterator, Symbol.unscopables, "entries", "keys",
|
||||
"values", "constructor"];
|
||||
"values", "constructor", "flat", "flatMap"];
|
||||
if (isNightlyBuild) {
|
||||
// ...nothing now
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue