120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
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;
 | 
						|
};
 |