var global = require('../internals/global'); var bind = require('../internals/function-bind-context'); var uncurryThis = require('../internals/function-uncurry-this'); var IndexedObject = require('../internals/indexed-object'); var toObject = require('../internals/to-object'); var toPropertyKey = require('../internals/to-property-key'); var lengthOfArrayLike = require('../internals/length-of-array-like'); var objectCreate = require('../internals/object-create'); var arrayFromConstructorAndList = require('../internals/array-from-constructor-and-list'); var Array = global.Array; var push = uncurryThis([].push); module.exports = function ($this, callbackfn, that, specificConstructor) { var O = toObject($this); var self = IndexedObject(O); var boundFunction = bind(callbackfn, that); var target = objectCreate(null); var length = lengthOfArrayLike(self); var index = 0; var Constructor, key, value; for (;length > index; index++) { value = self[index]; key = toPropertyKey(boundFunction(value, index, O)); // in some IE10 builds, `hasOwnProperty` returns incorrect result on integer keys // but since it's a `null` prototype object, we can safely use `in` if (key in target) push(target[key], value); else target[key] = [value]; } if (specificConstructor) { Constructor = specificConstructor(O); if (Constructor !== Array) { for (key in target) target[key] = arrayFromConstructorAndList(Constructor, target[key]); } } return target; };