// async series collection
// lightweight async iterators (map, each, reduce, filter, reject)
// adpoted from: https://github.com/aliaksandr-pasynkau/async-iterate

var keys    = require('../object/keys')
var isArray = require('../lang/isArray')

function asyncEachArray (arr, iterator, done) {
  if (!arr || !arr.length) {
    done()
    return
  }

  var lastIdx = arr.length
  var iterate = function (idx) {
    if (idx === lastIdx) return done()

    iterator(arr[idx], idx, function (err) {
      if (err) return done(err)

      iterate(++idx)
    })
  }
  iterate(0)
}

function asyncEach (obj, iterator, done) {
  if (isArray(obj)) {
    asyncEachArray(obj, iterator, done)
    return
  }

  asyncEachArray(obj && keys(obj), function (key, index, done) {
    iterator(obj[key], key, done)
  }, done)
}

function asyncReduce (obj, result, iterator, done) {
  asyncEach(obj, function (v, k, done) {
    iterator(result, v, k, function (err, value) {
      result = value
      done(err)
    })
  }, function (err) {
      done(err, result)
  })
}

function asyncMap (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      resultObject.push(result)
      done(err, resultObject)
    })
  }, done)
}

function asyncFilter (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

function asyncReject (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (!result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

exports.map = asyncMap
exports.each = asyncEach
exports.reduce = asyncReduce
exports.filter = asyncFilter
exports.reject = asyncReject

@@ -1768,16 +1768,754 @@
 one)%0A%7D%0A%0A
+function asyncEvery (obj, iterator, done) %7B%0A  asyncReduce(obj, true, function (resultObject, v, k, done) %7B%0A    iterator(v, k, function (err, result) %7B%0A      if (!result) resultObject = false%0A      done(err, resultObject)%0A    %7D)%0A  %7D, done)%0A%7D%0A%0Afunction asyncSome (obj, iterator, done) %7B%0A  asyncReduce(obj, false, function (resultObject, v, k, done) %7B%0A    iterator(v, k, function (err, result) %7B%0A      if (result) resultObject = true%0A      done(err, resultObject)%0A    %7D)%0A  %7D, done)%0A%7D%0A%0Afunction asyncConcat (obj, iterator, done) %7B%0A  asyncReduce(obj, %5B%5D, function (resultObject, v, k, done) %7B%0A    iterator(v, k, function (err, result) %7B%0A      resultObject = resultObject.concat(result %7C%7C %5B%5D)%0A      done(err, resultObject)%0A    %7D)%0A  %7D, done)%0A%7D%0A%0A
 exports.
@@ -2518,16 +2518,19 @@
 rts.map 
+   
 = asyncM
@@ -2545,16 +2545,18 @@
 ts.each 
+  
 = asyncE
@@ -2646,8 +2646,92 @@
 cReject%0A
+exports.every  = asyncEvery%0Aexports.some   = asyncSome%0Aexports.concat = asyncConcat%0A

update async/iterate