blob: 5422ad30d8aaffab0dc13c4d4917d65a6a410810 [file] [log] [blame]
'use strict';
var ctx = require('./_ctx');
var $export = require('./_export');
var createDesc = require('./_property-desc');
var assign = require('./_object-assign');
var create = require('./_object-create');
var getPrototypeOf = require('./_object-gpo');
var getKeys = require('./_object-keys');
var dP = require('./_object-dp');
var keyOf = require('./_keyof');
var aFunction = require('./_a-function');
var forOf = require('./_for-of');
var isIterable = require('./core.is-iterable');
var $iterCreate = require('./_iter-create');
var step = require('./_iter-step');
var isObject = require('./_is-object');
var toIObject = require('./_to-iobject');
var DESCRIPTORS = require('./_descriptors');
var has = require('./_has');
// 0 -> Dict.forEach
// 1 -> Dict.map
// 2 -> Dict.filter
// 3 -> Dict.some
// 4 -> Dict.every
// 5 -> Dict.find
// 6 -> Dict.findKey
// 7 -> Dict.mapPairs
var createDictMethod = function (TYPE) {
var IS_MAP = TYPE == 1;
var IS_EVERY = TYPE == 4;
return function (object, callbackfn, that /* = undefined */) {
var f = ctx(callbackfn, that, 3);
var O = toIObject(object);
var result = IS_MAP || TYPE == 7 || TYPE == 2
? new (typeof this == 'function' ? this : Dict)() : undefined;
var key, val, res;
for (key in O) if (has(O, key)) {
val = O[key];
res = f(val, key, object);
if (TYPE) {
if (IS_MAP) result[key] = res; // map
else if (res) switch (TYPE) {
case 2: result[key] = val; break; // filter
case 3: return true; // some
case 5: return val; // find
case 6: return key; // findKey
case 7: result[res[0]] = res[1]; // mapPairs
} else if (IS_EVERY) return false; // every
}
}
return TYPE == 3 || IS_EVERY ? IS_EVERY : result;
};
};
var findKey = createDictMethod(6);
var createDictIter = function (kind) {
return function (it) {
return new DictIterator(it, kind);
};
};
var DictIterator = function (iterated, kind) {
this._t = toIObject(iterated); // target
this._a = getKeys(iterated); // keys
this._i = 0; // next index
this._k = kind; // kind
};
$iterCreate(DictIterator, 'Dict', function () {
var that = this;
var O = that._t;
var keys = that._a;
var kind = that._k;
var key;
do {
if (that._i >= keys.length) {
that._t = undefined;
return step(1);
}
} while (!has(O, key = keys[that._i++]));
if (kind == 'keys') return step(0, key);
if (kind == 'values') return step(0, O[key]);
return step(0, [key, O[key]]);
});
function Dict(iterable) {
var dict = create(null);
if (iterable != undefined) {
if (isIterable(iterable)) {
forOf(iterable, true, function (key, value) {
dict[key] = value;
});
} else assign(dict, iterable);
}
return dict;
}
Dict.prototype = null;
function reduce(object, mapfn, init) {
aFunction(mapfn);
var O = toIObject(object);
var keys = getKeys(O);
var length = keys.length;
var i = 0;
var memo, key;
if (arguments.length < 3) {
if (!length) throw TypeError('Reduce of empty object with no initial value');
memo = O[keys[i++]];
} else memo = Object(init);
while (length > i) if (has(O, key = keys[i++])) {
memo = mapfn(memo, O[key], key, object);
}
return memo;
}
function includes(object, el) {
// eslint-disable-next-line no-self-compare
return (el == el ? keyOf(object, el) : findKey(object, function (it) {
// eslint-disable-next-line no-self-compare
return it != it;
})) !== undefined;
}
function get(object, key) {
if (has(object, key)) return object[key];
}
function set(object, key, value) {
if (DESCRIPTORS && key in Object) dP.f(object, key, createDesc(0, value));
else object[key] = value;
return object;
}
function isDict(it) {
return isObject(it) && getPrototypeOf(it) === Dict.prototype;
}
$export($export.G + $export.F, { Dict: Dict });
$export($export.S, 'Dict', {
keys: createDictIter('keys'),
values: createDictIter('values'),
entries: createDictIter('entries'),
forEach: createDictMethod(0),
map: createDictMethod(1),
filter: createDictMethod(2),
some: createDictMethod(3),
every: createDictMethod(4),
find: createDictMethod(5),
findKey: findKey,
mapPairs: createDictMethod(7),
reduce: reduce,
keyOf: keyOf,
includes: includes,
has: has,
get: get,
set: set,
isDict: isDict
});