Skip to content

Commit 6c5f5a1

Browse files
committed
add object map/reduce/filter
1 parent 900e39c commit 6c5f5a1

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ Fast['try'] = Fast.attempt = require( './function/try' );
3838

3939
Fast.assign = require('./object/assign');
4040
Fast.cloneObject = require('./object/clone');
41+
Fast.mapObject = require('./object/map');
42+
Fast.filterObject = require('./object/filter');
43+
Fast.reduceObject = require('./object/reduce');
4144

4245
Fast.cloneArray = require('./array/clone');
4346
Fast.concat = require('./array/concat');

object/filter.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
var bindInternal3 = require('../function/bindInternal3');
4+
5+
/**
6+
* # Filter
7+
*
8+
* A fast object `.filter()` implementation.
9+
*
10+
* @param {Object} subject The object to filter.
11+
* @param {Function} fn The filter function.
12+
* @param {Object} thisContext The context for the filter.
13+
* @return {Object} The new object containing the filtered results.
14+
*/
15+
module.exports = function fastFilterObject (subject, fn, thisContext) {
16+
var keys = Object.keys(subject),
17+
length = keys.length,
18+
result = {},
19+
iterator = thisContext !== undefined ? bindInternal3(fn, thisContext) : fn,
20+
i, key;
21+
for (i = 0; i < length; i++) {
22+
key = keys[i];
23+
if (iterator(subject[key], key, subject)) {
24+
result[key] = subject[key];
25+
}
26+
}
27+
return result;
28+
};

object/map.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
var bindInternal3 = require('../function/bindInternal3');
4+
5+
/**
6+
* # Map
7+
*
8+
* A fast object `.map()` implementation.
9+
*
10+
* @param {Object} subject The object to map over.
11+
* @param {Function} fn The mapper function.
12+
* @param {Object} thisContext The context for the mapper.
13+
* @return {Object} The new object containing the results.
14+
*/
15+
module.exports = function fastMapObject (subject, fn, thisContext) {
16+
var keys = Object.keys(subject),
17+
length = keys.length,
18+
result = {},
19+
iterator = thisContext !== undefined ? bindInternal3(fn, thisContext) : fn,
20+
i, key;
21+
for (i = 0; i < length; i++) {
22+
key = keys[i];
23+
result[key] = iterator(subject[key], key, subject);
24+
}
25+
return result;
26+
};

object/reduce.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
var bindInternal4 = require('../function/bindInternal4');
4+
5+
/**
6+
* # Reduce
7+
*
8+
* A fast object `.reduce()` implementation.
9+
*
10+
* @param {Object} subject The object to reduce over.
11+
* @param {Function} fn The reducer function.
12+
* @param {mixed} initialValue The initial value for the reducer, defaults to subject[0].
13+
* @param {Object} thisContext The context for the reducer.
14+
* @return {mixed} The final result.
15+
*/
16+
module.exports = function fastReduceObject (subject, fn, initialValue, thisContext) {
17+
var keys = Object.keys(subject),
18+
length = keys.length,
19+
iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,
20+
i, key, result;
21+
22+
if (initialValue === undefined) {
23+
i = 1;
24+
result = subject[keys[0]];
25+
}
26+
else {
27+
i = 0;
28+
result = initialValue;
29+
}
30+
31+
for (; i < length; i++) {
32+
key = keys[i];
33+
result = iterator(result, subject[key], key, subject);
34+
}
35+
36+
return result;
37+
};

test/test.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,85 @@ describe('fast.intern()', function () {
726726
});
727727
});
728728

729+
describe('fast.mapObject', function () {
730+
it('should map over the keys / values in an object', function () {
731+
var result = fast.mapObject({a: 1, b: 2, c: 3}, function (value, key) {
732+
return [key, value];
733+
});
734+
result.should.eql({
735+
a: ["a", 1],
736+
b: ["b", 2],
737+
c: ["c", 3]
738+
});
739+
});
740+
it('should map over the keys / values in an object, with a context', function () {
741+
var context = {val: 1};
742+
var result = fast.mapObject({a: 1, b: 2, c: 3}, function (value, key) {
743+
return [key, value + this.val];
744+
}, context);
745+
result.should.eql({
746+
a: ["a", 2],
747+
b: ["b", 3],
748+
c: ["c", 4]
749+
});
750+
});
751+
});
752+
753+
describe('fast.filterObject', function () {
754+
it('should filter keys / values from an object', function () {
755+
var result = fast.filterObject({a: 1, b: 2, c: 3, d: 4}, function (value) {
756+
return (value % 2) === 0;
757+
});
758+
result.should.eql({
759+
b: 2,
760+
d: 4
761+
});
762+
});
763+
it('should filter keys / values from an object, with a context', function () {
764+
var context = {val: 1};
765+
var result = fast.filterObject({a: 1, b: 2, c: 3, d: 4}, function (value) {
766+
return ((value + this.val) % 2) === 0;
767+
}, context);
768+
result.should.eql({
769+
a: 1,
770+
c: 3
771+
});
772+
});
773+
});
774+
775+
describe('fast.reduceObject', function () {
776+
it('should apply a reducer to an object', function () {
777+
var result = fast.reduceObject({a: 1, b: 2, c: 3, d: 4}, function (total, value, key) {
778+
return total + value;
779+
},0);
780+
781+
result.should.equal(10);
782+
});
783+
784+
it('should apply a reducer to an object, with a context', function () {
785+
var context = {val:1};
786+
var result = fast.reduceObject({a: 1, b: 2, c: 3, d: 4}, function (total, value, key) {
787+
return total + value + this.val;
788+
},0, context);
789+
790+
result.should.equal(14);
791+
});
792+
793+
it('should apply a reducer to an object, with no initial value', function () {
794+
var result = fast.reduceObject({a: 1, b: 2, c: 3, d: 4}, function (acc, value, key) {
795+
return acc + value + 1;
796+
});
797+
result.should.equal(13);
798+
});
799+
it('should apply a reducer to an object, with no initial value, with a context', function () {
800+
var context = {val: 1};
801+
var result = fast.reduceObject({a: 1, b: 2, c: 3, d: 4}, function (acc, value, key) {
802+
return acc + value + this.val;
803+
}, undefined, context);
804+
result.should.equal(13);
805+
});
806+
});
807+
729808
describe('Fast', function () {
730809
var input = fast([1,2,3,4,5,6]);
731810

0 commit comments

Comments
 (0)