Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter, reject, detect, some, every with error #1028

Merged
merged 2 commits into from
Feb 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ async.map(['file1','file2','file3'], fs.stat, function(err, results){
// results is now an array of stats for each file
});

async.filter(['file1','file2','file3'], fs.exists, function(results){
async.filter(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, results){
// results now equals an array of the existing files
});

Expand Down Expand Up @@ -395,25 +399,26 @@ __Related__
__Alias:__ `select`

Returns a new array of all the values in `arr` which pass an async truth test.
_The callback for each `iteratee` call only accepts a single argument of `true` or
`false`; it does not accept an error argument first!_ This is in-line with the
way node libraries work with truth tests like `fs.exists`. This operation is
performed in parallel, but the results array will be in the same order as the
original.
This operation is performed in parallel,
but the results array will be in the same order as the original.

__Arguments__

* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
The `iteratee` is passed a `callback(truthValue)`, which must be called with a
The `iteratee` is passed a `callback(err, truthValue)`, which must be called with a
boolean argument once it has completed.
* `callback(results)` - *Optional* A callback which is called after all the `iteratee`
* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee`
functions have finished.

__Example__

```js
async.filter(['file1','file2','file3'], fs.exists, function(results){
async.filter(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, results){
// results now equals an array of the existing files
});
```
Expand Down Expand Up @@ -502,17 +507,21 @@ __Arguments__

* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
The iteratee is passed a `callback(truthValue)` which must be called with a
boolean argument once it has completed. **Note: this callback does not take an error as its first argument.**
* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
The iteratee is passed a `callback(err, truthValue)` which must be called with a
boolean argument once it has completed.
* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
`true`, or after all the `iteratee` functions have finished. Result will be
the first item in the array that passes the truth test (iteratee) or the
value `undefined` if none passed. **Note: this callback does not take an error as its first argument.**
value `undefined` if none passed.

__Example__

```js
async.detect(['file1','file2','file3'], fs.exists, function(result){
async.detect(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result){
// result now equals the first file in the list that exists
});
```
Expand Down Expand Up @@ -581,26 +590,26 @@ async.sortBy([1,9,3,5], function(x, callback){
__Alias:__ `any`

Returns `true` if at least one element in the `arr` satisfies an async test.
_The callback for each iteratee call only accepts a single argument of `true` or
`false`; it does not accept an error argument first!_ This is in-line with the
way node libraries work with truth tests like `fs.exists`. Once any iteratee
call returns `true`, the main `callback` is immediately called.
If any iteratee call returns `true`, the main `callback` is immediately called.

__Arguments__

* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in the array
in parallel. The iteratee is passed a `callback(truthValue)`` which must be
called with a boolean argument once it has completed.
* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
`true`, or after all the iteratee functions have finished. Result will be
either `true` or `false` depending on the values of the async tests.

**Note: the callbacks do not take an error as their first argument.**
__Example__

```js
async.some(['file1','file2','file3'], fs.exists, function(result){
async.some(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result){
// if result is true then at least one of the files exists
});
```
Expand All @@ -617,26 +626,26 @@ __Related__
__Alias:__ `all`

Returns `true` if every element in `arr` satisfies an async test.
_The callback for each `iteratee` call only accepts a single argument of `true` or
`false`; it does not accept an error argument first!_ This is in-line with the
way node libraries work with truth tests like `fs.exists`.
If any iteratee call returns `false`, the main `callback` is immediately called.

__Arguments__

* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in the array
in parallel. The iteratee is passed a `callback(truthValue)` which must be
in parallel. The iteratee is passed a `callback(err, truthValue)` which must be
called with a boolean argument once it has completed.
* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
`false`, or after all the iteratee functions have finished. Result will be
either `true` or `false` depending on the values of the async tests.

**Note: the callbacks do not take an error as their first argument.**
* `callback(err, result)` - *Optional* A callback which is called after all the `iteratee`
functions have finished. Result will be either `true` or `false` depending on
the values of the async tests.

__Example__

```js
async.every(['file1','file2','file3'], fs.exists, function(result){
async.every(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result){
// if result is true then every file exists
});
```
Expand Down
23 changes: 17 additions & 6 deletions lib/internal/createTester.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,26 @@

export default function _createTester(eachfn, check, getResult) {
return function(arr, limit, iterator, cb) {
function done() {
if (cb) cb(getResult(false, void 0));
function done(err) {
if (cb) {
if (err) {
cb(err);
} else {
cb(null, getResult(false, void 0));
}
}
}
function iteratee(x, _, callback) {
if (!cb) return callback();
iterator(x, function (v) {
if (cb && check(v)) {
cb(getResult(true, x));
cb = iterator = false;
iterator(x, function (err, v) {
if (cb) {
if (err) {
cb(err);
cb = iterator = false;
} else if (check(v)) {
cb(null, getResult(true, x));
cb = iterator = false;
}
}
callback();
});
Expand Down
26 changes: 18 additions & 8 deletions lib/internal/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,25 @@ import property from 'lodash/_baseProperty';
export default function _filter(eachfn, arr, iterator, callback) {
var results = [];
eachfn(arr, function (x, index, callback) {
iterator(x, function (v) {
if (v) {
results.push({index: index, value: x});
iterator(x, function (err, v) {
if (err) {
callback(err);
}
else {
if (v) {
results.push({index: index, value: x});
}
callback();
}
callback();
});
}, function () {
callback(arrayMap(results.sort(function (a, b) {
return a.index - b.index;
}), property('value')));
}, function (err) {
if (err) {
callback(err);
}
else {
callback(null, arrayMap(results.sort(function (a, b) {
return a.index - b.index;
}), property('value')));
}
});
}
8 changes: 6 additions & 2 deletions lib/internal/reject.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import filter from './filter';

export default function reject(eachfn, arr, iterator, callback) {
filter(eachfn, arr, function(value, cb) {
iterator(value, function(v) {
cb(!v);
iterator(value, function(err, v) {
if (err) {
cb(err);
} else {
cb(null, !v);
}
});
}, callback);
}
Loading