1// 0 -> Array#forEach
2// 1 -> Array#map
3// 2 -> Array#filter
4// 3 -> Array#some
5// 4 -> Array#every
6// 5 -> Array#find
7// 6 -> Array#findIndex
8var ctx = require('./_ctx');
9var IObject = require('./_iobject');
10var toObject = require('./_to-object');
11var toLength = require('./_to-length');
12var asc = require('./_array-species-create');
13module.exports = function (TYPE, $create) {
14  var IS_MAP = TYPE == 1;
15  var IS_FILTER = TYPE == 2;
16  var IS_SOME = TYPE == 3;
17  var IS_EVERY = TYPE == 4;
18  var IS_FIND_INDEX = TYPE == 6;
19  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
20  var create = $create || asc;
21  return function ($this, callbackfn, that) {
22    var O = toObject($this);
23    var self = IObject(O);
24    var f = ctx(callbackfn, that, 3);
25    var length = toLength(self.length);
26    var index = 0;
27    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
28    var val, res;
29    for (;length > index; index++) if (NO_HOLES || index in self) {
30      val = self[index];
31      res = f(val, index, O);
32      if (TYPE) {
33        if (IS_MAP) result[index] = res;   // map
34        else if (res) switch (TYPE) {
35          case 3: return true;             // some
36          case 5: return val;              // find
37          case 6: return index;            // findIndex
38          case 2: result.push(val);        // filter
39        } else if (IS_EVERY) return false; // every
40      }
41    }
42    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
43  };
44};
45