core.dict.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. 'use strict';
  2. var $ = require('./$')
  3. , ctx = require('./$.ctx')
  4. , $export = require('./$.export')
  5. , createDesc = require('./$.property-desc')
  6. , assign = require('./$.object-assign')
  7. , keyOf = require('./$.keyof')
  8. , aFunction = require('./$.a-function')
  9. , forOf = require('./$.for-of')
  10. , isIterable = require('./core.is-iterable')
  11. , $iterCreate = require('./$.iter-create')
  12. , step = require('./$.iter-step')
  13. , isObject = require('./$.is-object')
  14. , toIObject = require('./$.to-iobject')
  15. , DESCRIPTORS = require('./$.descriptors')
  16. , has = require('./$.has')
  17. , getKeys = $.getKeys;
  18. // 0 -> Dict.forEach
  19. // 1 -> Dict.map
  20. // 2 -> Dict.filter
  21. // 3 -> Dict.some
  22. // 4 -> Dict.every
  23. // 5 -> Dict.find
  24. // 6 -> Dict.findKey
  25. // 7 -> Dict.mapPairs
  26. var createDictMethod = function(TYPE){
  27. var IS_MAP = TYPE == 1
  28. , IS_EVERY = TYPE == 4;
  29. return function(object, callbackfn, that /* = undefined */){
  30. var f = ctx(callbackfn, that, 3)
  31. , O = toIObject(object)
  32. , result = IS_MAP || TYPE == 7 || TYPE == 2
  33. ? new (typeof this == 'function' ? this : Dict) : undefined
  34. , key, val, res;
  35. for(key in O)if(has(O, key)){
  36. val = O[key];
  37. res = f(val, key, object);
  38. if(TYPE){
  39. if(IS_MAP)result[key] = res; // map
  40. else if(res)switch(TYPE){
  41. case 2: result[key] = val; break; // filter
  42. case 3: return true; // some
  43. case 5: return val; // find
  44. case 6: return key; // findKey
  45. case 7: result[res[0]] = res[1]; // mapPairs
  46. } else if(IS_EVERY)return false; // every
  47. }
  48. }
  49. return TYPE == 3 || IS_EVERY ? IS_EVERY : result;
  50. };
  51. };
  52. var findKey = createDictMethod(6);
  53. var createDictIter = function(kind){
  54. return function(it){
  55. return new DictIterator(it, kind);
  56. };
  57. };
  58. var DictIterator = function(iterated, kind){
  59. this._t = toIObject(iterated); // target
  60. this._a = getKeys(iterated); // keys
  61. this._i = 0; // next index
  62. this._k = kind; // kind
  63. };
  64. $iterCreate(DictIterator, 'Dict', function(){
  65. var that = this
  66. , O = that._t
  67. , keys = that._a
  68. , kind = that._k
  69. , key;
  70. do {
  71. if(that._i >= keys.length){
  72. that._t = undefined;
  73. return step(1);
  74. }
  75. } while(!has(O, key = keys[that._i++]));
  76. if(kind == 'keys' )return step(0, key);
  77. if(kind == 'values')return step(0, O[key]);
  78. return step(0, [key, O[key]]);
  79. });
  80. function Dict(iterable){
  81. var dict = $.create(null);
  82. if(iterable != undefined){
  83. if(isIterable(iterable)){
  84. forOf(iterable, true, function(key, value){
  85. dict[key] = value;
  86. });
  87. } else assign(dict, iterable);
  88. }
  89. return dict;
  90. }
  91. Dict.prototype = null;
  92. function reduce(object, mapfn, init){
  93. aFunction(mapfn);
  94. var O = toIObject(object)
  95. , keys = getKeys(O)
  96. , length = keys.length
  97. , i = 0
  98. , memo, key;
  99. if(arguments.length < 3){
  100. if(!length)throw TypeError('Reduce of empty object with no initial value');
  101. memo = O[keys[i++]];
  102. } else memo = Object(init);
  103. while(length > i)if(has(O, key = keys[i++])){
  104. memo = mapfn(memo, O[key], key, object);
  105. }
  106. return memo;
  107. }
  108. function includes(object, el){
  109. return (el == el ? keyOf(object, el) : findKey(object, function(it){
  110. return it != it;
  111. })) !== undefined;
  112. }
  113. function get(object, key){
  114. if(has(object, key))return object[key];
  115. }
  116. function set(object, key, value){
  117. if(DESCRIPTORS && key in Object)$.setDesc(object, key, createDesc(0, value));
  118. else object[key] = value;
  119. return object;
  120. }
  121. function isDict(it){
  122. return isObject(it) && $.getProto(it) === Dict.prototype;
  123. }
  124. $export($export.G + $export.F, {Dict: Dict});
  125. $export($export.S, 'Dict', {
  126. keys: createDictIter('keys'),
  127. values: createDictIter('values'),
  128. entries: createDictIter('entries'),
  129. forEach: createDictMethod(0),
  130. map: createDictMethod(1),
  131. filter: createDictMethod(2),
  132. some: createDictMethod(3),
  133. every: createDictMethod(4),
  134. find: createDictMethod(5),
  135. findKey: findKey,
  136. mapPairs: createDictMethod(7),
  137. reduce: reduce,
  138. keyOf: keyOf,
  139. includes: includes,
  140. has: has,
  141. get: get,
  142. set: set,
  143. isDict: isDict
  144. });