Spaces:
Runtime error
Runtime error
; | |
var iteratorSymbol = require("es6-symbol").iterator | |
, isArguments = require("../../function/is-arguments") | |
, isFunction = require("../../function/is-function") | |
, toPosInt = require("../../number/to-pos-integer") | |
, callable = require("../../object/valid-callable") | |
, validValue = require("../../object/valid-value") | |
, isValue = require("../../object/is-value") | |
, isString = require("../../string/is-string") | |
, isArray = Array.isArray | |
, call = Function.prototype.call | |
, desc = { configurable: true, enumerable: true, writable: true, value: null } | |
, defineProperty = Object.defineProperty; | |
// eslint-disable-next-line complexity, max-lines-per-function | |
module.exports = function (arrayLike /*, mapFn, thisArg*/) { | |
var mapFn = arguments[1] | |
, thisArg = arguments[2] | |
, Context | |
, i | |
, j | |
, arr | |
, length | |
, code | |
, iterator | |
, result | |
, getIterator | |
, value; | |
arrayLike = Object(validValue(arrayLike)); | |
if (isValue(mapFn)) callable(mapFn); | |
if (!this || this === Array || !isFunction(this)) { | |
// Result: Plain array | |
if (!mapFn) { | |
if (isArguments(arrayLike)) { | |
// Source: Arguments | |
length = arrayLike.length; | |
if (length !== 1) return Array.apply(null, arrayLike); | |
arr = new Array(1); | |
arr[0] = arrayLike[0]; | |
return arr; | |
} | |
if (isArray(arrayLike)) { | |
// Source: Array | |
arr = new Array((length = arrayLike.length)); | |
for (i = 0; i < length; ++i) arr[i] = arrayLike[i]; | |
return arr; | |
} | |
} | |
arr = []; | |
} else { | |
// Result: Non plain array | |
Context = this; | |
} | |
if (!isArray(arrayLike)) { | |
if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) { | |
// Source: Iterator | |
iterator = callable(getIterator).call(arrayLike); | |
if (Context) arr = new Context(); | |
result = iterator.next(); | |
i = 0; | |
while (!result.done) { | |
value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value; | |
if (Context) { | |
desc.value = value; | |
defineProperty(arr, i, desc); | |
} else { | |
arr[i] = value; | |
} | |
result = iterator.next(); | |
++i; | |
} | |
length = i; | |
} else if (isString(arrayLike)) { | |
// Source: String | |
length = arrayLike.length; | |
if (Context) arr = new Context(); | |
for (i = 0, j = 0; i < length; ++i) { | |
value = arrayLike[i]; | |
if (i + 1 < length) { | |
code = value.charCodeAt(0); | |
// eslint-disable-next-line max-depth | |
if (code >= 0xd800 && code <= 0xdbff) value += arrayLike[++i]; | |
} | |
value = mapFn ? call.call(mapFn, thisArg, value, j) : value; | |
if (Context) { | |
desc.value = value; | |
defineProperty(arr, j, desc); | |
} else { | |
arr[j] = value; | |
} | |
++j; | |
} | |
length = j; | |
} | |
} | |
if (length === undefined) { | |
// Source: array or array-like | |
length = toPosInt(arrayLike.length); | |
if (Context) arr = new Context(length); | |
for (i = 0; i < length; ++i) { | |
value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i]; | |
if (Context) { | |
desc.value = value; | |
defineProperty(arr, i, desc); | |
} else { | |
arr[i] = value; | |
} | |
} | |
} | |
if (Context) { | |
desc.value = null; | |
arr.length = length; | |
} | |
return arr; | |
}; | |