Skip to content

Commit 9ca19c1

Browse files
author
Caolan McMahon
committed
Added detect, reject, reduceRight and sortBy functions and added a few common aliases
1 parent c682809 commit 9ca19c1

File tree

2 files changed

+216
-7
lines changed

2 files changed

+216
-7
lines changed

lib/async.js

+69-6
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ var doSeries = function(fn){
5454

5555
var _map = function(eachfn, arr, iterator, callback){
5656
var results = [];
57-
for(var i=0; i<arr.length; i++){
58-
arr[i] = {index: i, value: arr[i]};
59-
}
57+
arr = arr.map(function(x, i){
58+
return {index: i, value: x};
59+
});
6060
eachfn(arr, function(x, callback){
6161
iterator(x.value, function(err, v){
6262
results[x.index] = v;
@@ -82,13 +82,23 @@ exports.reduce = function(arr, memo, iterator, callback){
8282
callback(err, memo);
8383
});
8484
};
85+
// inject alias
86+
exports.inject = exports.reduce;
87+
// foldl alias
88+
exports.foldl = exports.reduce;
8589

90+
exports.reduceRight = function(arr, memo, iterator, callback){
91+
var reversed = arr.map(function(x){return x;}).reverse();
92+
exports.reduce(reversed, memo, iterator, callback);
93+
};
94+
// foldr alias
95+
exports.foldr = exports.reduceRight;
8696

8797
var _filter = function(eachfn, arr, iterator, callback){
8898
var results = [];
89-
for(var i=0; i<arr.length; i++){
90-
arr[i] = {index: i, value: arr[i]};
91-
}
99+
arr = arr.map(function(x, i){
100+
return {index: i, value: x};
101+
});
92102
eachfn(arr, function(x, callback){
93103
iterator(x.value, function(v){
94104
if(v) results.push(x);
@@ -104,7 +114,42 @@ var _filter = function(eachfn, arr, iterator, callback){
104114
};
105115
exports.filter = doParallel(_filter);
106116
exports.filterSeries = doSeries(_filter);
117+
// select alias
118+
exports.select = exports.filter;
119+
exports.selectSeries = exports.filterSeries;
107120

121+
var _reject = function(eachfn, arr, iterator, callback){
122+
var results = [];
123+
arr = arr.map(function(x, i){
124+
return {index: i, value: x};
125+
});
126+
eachfn(arr, function(x, callback){
127+
iterator(x.value, function(v){
128+
if(!v) results.push(x);
129+
callback();
130+
});
131+
}, function(err){
132+
callback(results.sort(function(a,b){
133+
return a.index - b.index;
134+
}).map(function(x){
135+
return x.value;
136+
}));
137+
});
138+
};
139+
exports.reject = doParallel(_reject);
140+
exports.rejectSeries = doSeries(_reject);
141+
142+
var _detect = function(eachfn, arr, iterator, main_callback){
143+
eachfn(arr, function(x, callback){
144+
iterator(x, function(result){
145+
result ? main_callback(x): callback();
146+
});
147+
}, function(err){
148+
main_callback();
149+
});
150+
};
151+
exports.detect = doParallel(_detect);
152+
exports.detectSeries = doSeries(_detect);
108153

109154
exports.some = function(arr, iterator, main_callback){
110155
exports.forEach(arr, function(x, callback){
@@ -119,6 +164,8 @@ exports.some = function(arr, iterator, main_callback){
119164
main_callback(false);
120165
});
121166
};
167+
// any alias
168+
exports.any = exports.some;
122169

123170
exports.every = function(arr, iterator, main_callback){
124171
exports.forEach(arr, function(x, callback){
@@ -133,7 +180,23 @@ exports.every = function(arr, iterator, main_callback){
133180
main_callback(true);
134181
});
135182
};
183+
// all alias
184+
exports.all = exports.every;
136185

186+
exports.sortBy = function(arr, iterator, callback){
187+
exports.map(arr, function(x, callback){
188+
iterator(x, function(err, criteria){
189+
if(err) callback(err);
190+
else callback(null, {value: x, criteria: criteria});
191+
});
192+
}, function(err, results){
193+
if(err) return callback(err);
194+
else callback(null, results.sort(function(left, right){
195+
var a = left.criteria, b = right.criteria;
196+
return a < b ? -1 : a > b ? 1 : 0;
197+
}).map(function(x){return x.value;}));
198+
})
199+
};
137200

138201
exports.auto = function(tasks, callback){
139202
callback = callback || function(){};

test/test-async.js

+147-1
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,17 @@ exports['map'] = function(test){
437437
});
438438
};
439439

440+
exports['map original untouched'] = function(test){
441+
var a = [1,2,3];
442+
async.map(a, function(x, callback){
443+
callback(null, x*2);
444+
}, function(err, results){
445+
test.same(results, [2,4,6]);
446+
test.same(a, [1,2,3]);
447+
test.done();
448+
});
449+
};
450+
440451
exports['map error'] = function(test){
441452
test.expect(1);
442453
async.map([1,2,3], function(x, callback){
@@ -472,10 +483,13 @@ exports['mapSeries error'] = function(test){
472483
};
473484

474485
exports['reduce'] = function(test){
475-
async.reduce([1,3,2], 0, function(a, x, callback){
486+
var call_order = [];
487+
async.reduce([1,2,3], 0, function(a, x, callback){
488+
call_order.push(x);
476489
callback(null, a + x);
477490
}, function(err, result){
478491
test.equals(result, 6);
492+
test.same(call_order, [1,2,3]);
479493
test.done();
480494
});
481495
};
@@ -499,6 +513,35 @@ exports['reduce error'] = function(test){
499513
setTimeout(test.done, 50);
500514
};
501515

516+
exports['inject alias'] = function(test){
517+
test.equals(async.inject, async.reduce);
518+
test.done();
519+
};
520+
521+
exports['foldl alias'] = function(test){
522+
test.equals(async.foldl, async.reduce);
523+
test.done();
524+
};
525+
526+
exports['reduceRight'] = function(test){
527+
var call_order = [];
528+
var a = [1,2,3];
529+
async.reduceRight(a, 0, function(a, x, callback){
530+
call_order.push(x);
531+
callback(null, a + x);
532+
}, function(err, result){
533+
test.equals(result, 6);
534+
test.same(call_order, [3,2,1]);
535+
test.same(a, [1,2,3]);
536+
test.done();
537+
});
538+
};
539+
540+
exports['foldr alias'] = function(test){
541+
test.equals(async.foldr, async.reduceRight);
542+
test.done();
543+
};
544+
502545
exports['filter'] = function(test){
503546
async.filter([3,1,2], function(x, callback){
504547
setTimeout(function(){callback(x % 2);}, x*25);
@@ -508,6 +551,17 @@ exports['filter'] = function(test){
508551
});
509552
};
510553

554+
exports['filter original untouched'] = function(test){
555+
var a = [3,1,2];
556+
async.filter(a, function(x, callback){
557+
callback(x % 2);
558+
}, function(results){
559+
test.same(results, [3,1]);
560+
test.same(a, [3,1,2]);
561+
test.done();
562+
});
563+
};
564+
511565
exports['filterSeries'] = function(test){
512566
async.filterSeries([3,1,2], function(x, callback){
513567
setTimeout(function(){callback(x % 2);}, x*25);
@@ -517,6 +571,45 @@ exports['filterSeries'] = function(test){
517571
});
518572
};
519573

574+
exports['select alias'] = function(test){
575+
test.equals(async.select, async.filter);
576+
test.done();
577+
};
578+
579+
exports['selectSeries alias'] = function(test){
580+
test.equals(async.selectSeries, async.filterSeries);
581+
test.done();
582+
};
583+
584+
exports['reject'] = function(test){
585+
async.reject([3,1,2], function(x, callback){
586+
setTimeout(function(){callback(x % 2);}, x*25);
587+
}, function(results){
588+
test.same(results, [2]);
589+
test.done();
590+
});
591+
};
592+
593+
exports['reject original untouched'] = function(test){
594+
var a = [3,1,2];
595+
async.reject(a, function(x, callback){
596+
callback(x % 2);
597+
}, function(results){
598+
test.same(results, [2]);
599+
test.same(a, [3,1,2]);
600+
test.done();
601+
});
602+
};
603+
604+
exports['rejectSeries'] = function(test){
605+
async.rejectSeries([3,1,2], function(x, callback){
606+
setTimeout(function(){callback(x % 2);}, x*25);
607+
}, function(results){
608+
test.same(results, [2]);
609+
test.done();
610+
});
611+
};
612+
520613
exports['some true'] = function(test){
521614
async.some([3,1,2], function(x, callback){
522615
process.nextTick(function(){
@@ -555,6 +648,11 @@ exports['some early return'] = function(test){
555648
}, 100);
556649
};
557650

651+
exports['any alias'] = function(test){
652+
test.equals(async.any, async.some);
653+
test.done();
654+
};
655+
558656
exports['every true'] = function(test){
559657
async.every([1,2,3], function(x, callback){
560658
process.nextTick(function(){callback(true);});
@@ -588,3 +686,51 @@ exports['every early return'] = function(test){
588686
test.done();
589687
}, 100);
590688
};
689+
690+
exports['all alias'] = function(test){
691+
test.equals(async.all, async.every);
692+
test.done();
693+
};
694+
695+
exports['detect'] = function(test){
696+
var call_order = [];
697+
async.detect([3,2,1], function(x, callback){
698+
setTimeout(function(){
699+
call_order.push(x);
700+
callback(x == 2);
701+
}, x*25);
702+
}, function(result){
703+
call_order.push('callback');
704+
test.equals(result, 2);
705+
});
706+
setTimeout(function(){
707+
test.same(call_order, [1,2,'callback',3]);
708+
test.done();
709+
}, 100);
710+
};
711+
712+
exports['detectSeries'] = function(test){
713+
var call_order = [];
714+
async.detectSeries([3,2,1], function(x, callback){
715+
setTimeout(function(){
716+
call_order.push(x);
717+
callback(x == 2);
718+
}, x*25);
719+
}, function(result){
720+
call_order.push('callback');
721+
test.equals(result, 2);
722+
});
723+
setTimeout(function(){
724+
test.same(call_order, [3,2,'callback']);
725+
test.done();
726+
}, 200);
727+
};
728+
729+
exports['sortBy'] = function(test){
730+
async.sortBy([{a:1},{a:15},{a:6}], function(x, callback){
731+
process.nextTick(function(){callback(null, x.a);});
732+
}, function(err, result){
733+
test.same(result, [{a:1},{a:6},{a:15}]);
734+
test.done();
735+
});
736+
};

0 commit comments

Comments
 (0)