| var anObject = require('../internals/an-object'); |
| var isArrayIteratorMethod = require('../internals/is-array-iterator-method'); |
| var toLength = require('../internals/to-length'); |
| var bind = require('../internals/bind-context'); |
| var getIteratorMethod = require('../internals/get-iterator-method'); |
| var callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing'); |
| |
| var Result = function (stopped, result) { |
| this.stopped = stopped; |
| this.result = result; |
| }; |
| |
| var iterate = module.exports = function (iterable, fn, that, AS_ENTRIES, IS_ITERATOR) { |
| var boundFunction = bind(fn, that, AS_ENTRIES ? 2 : 1); |
| var iterator, iterFn, index, length, result, next, step; |
| |
| if (IS_ITERATOR) { |
| iterator = iterable; |
| } else { |
| iterFn = getIteratorMethod(iterable); |
| if (typeof iterFn != 'function') throw TypeError('Target is not iterable'); |
| // optimisation for array iterators |
| if (isArrayIteratorMethod(iterFn)) { |
| for (index = 0, length = toLength(iterable.length); length > index; index++) { |
| result = AS_ENTRIES |
| ? boundFunction(anObject(step = iterable[index])[0], step[1]) |
| : boundFunction(iterable[index]); |
| if (result && result instanceof Result) return result; |
| } return new Result(false); |
| } |
| iterator = iterFn.call(iterable); |
| } |
| |
| next = iterator.next; |
| while (!(step = next.call(iterator)).done) { |
| result = callWithSafeIterationClosing(iterator, boundFunction, step.value, AS_ENTRIES); |
| if (typeof result == 'object' && result && result instanceof Result) return result; |
| } return new Result(false); |
| }; |
| |
| iterate.stop = function (result) { |
| return new Result(true, result); |
| }; |