Skip to content

Commit f7ed66e

Browse files
committed
Merge pull request #19 from tjmehta/inverse
add inverse
2 parents dd995fa + 84f241c commit f7ed66e

File tree

5 files changed

+193
-32
lines changed

5 files changed

+193
-32
lines changed

README.md

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,23 @@ Functional methods like forEach, map, filter, and other Array methods for Object
1010
# Index
1111

1212
[chain](https://github.com/tjmehta/object-loops#usage)
13+
1314
[every](https://github.com/tjmehta/object-loops#every)
14-
[find](https://github.com/tjmehta/object-loops#find)
15-
[findKey](https://github.com/tjmehta/object-loops#findKey)
15+
1616
[filter](https://github.com/tjmehta/object-loops#filter)
17+
18+
[findKey](https://github.com/tjmehta/object-loops#findKey)
19+
20+
[find](https://github.com/tjmehta/object-loops#find)
21+
1722
[forEach](https://github.com/tjmehta/object-loops#forEach)
23+
24+
[mapKeys](https://github.com/tjmehta/object-loops#mapKeys)
25+
1826
[map](https://github.com/tjmehta/object-loops#map)
27+
1928
[reduce](https://github.com/tjmehta/object-loops#reduce)
29+
2030
[some](https://github.com/tjmehta/object-loops#some)
2131

2232
# Usage
@@ -88,6 +98,35 @@ allGreaterThan25 // false
8898
*/
8999
```
90100

101+
## filter
102+
103+
Creates a new object with all entries that pass the test implemented by the provided function.
104+
105+
* @param {object} [obj] - object to filter values, not accepted if being used directly on Object.prototype
106+
* @param {function} callback - function to test each value in the object. return true to keep that entry, false otherwise.
107+
* @param {*} [thisArg] - optional. context to bind to callback
108+
* @returns {object} newly created object with filtered values
109+
110+
```js
111+
var filter = require('object-loops/filter')
112+
113+
var obj = {
114+
foo: 10,
115+
bar: 20,
116+
baz: 30,
117+
qux: 40,
118+
}
119+
var filteredObj = filter(obj, function (val, key, obj) {
120+
return val > 25
121+
})
122+
filteredObj /* Only has entries with vals greater than 25
123+
{
124+
baz: 30,
125+
qux: 40
126+
}
127+
*/
128+
```
129+
91130
## find
92131

93132
Find the value of the the object that passes the test implemented by the callback.
@@ -146,59 +185,59 @@ notfound // undefined
146185
*/
147186
```
148187

149-
## filter
188+
## forEach
150189

151-
Creates a new object with all entries that pass the test implemented by the provided function.
190+
Executes a provided function once per each object value.
152191

153-
* @param {object} [obj] - object to filter values, not accepted if being used directly on Object.prototype
154-
* @param {function} callback - function to test each value in the object. return true to keep that entry, false otherwise.
192+
* @param {object} [obj] - object to forEach, not accepted if being used directly on Object.prototype
193+
* @param {function} callback - function that will be invoked once for each key-value pair
155194
* @param {*} [thisArg] - optional. context to bind to callback
156-
* @returns {object} newly created object with filtered values
157195

158196
```js
159-
var filter = require('object-loops/filter')
197+
var forEach = require('object-loops/for-each')
160198

161199
var obj = {
162200
foo: 10,
163201
bar: 20,
164-
baz: 30,
165-
qux: 40,
202+
baz: 30
166203
}
167-
var filteredObj = filter(obj, function (val, key, obj) {
168-
return val > 25
204+
var keyConcat = ''
205+
var valSum = 0
206+
forEach(obj, function (val, key, obj) {
207+
keyConcat += key
208+
valSum += val
169209
})
170-
filteredObj /* Only has entries with vals greater than 25
171-
{
172-
baz: 30,
173-
qux: 40
174-
}
175-
*/
210+
keyConcat // = 'foobarbaz'
211+
valSum // = 60
176212
```
177213

178-
## forEach
214+
## mapKeys
179215

180-
Executes a provided function once per each object value.
216+
Creates a new object with the results of calling a provided function on every key in the object.
181217

182-
* @param {object} [obj] - object to forEach, not accepted if being used directly on Object.prototype
183-
* @param {function} callback - function that will be invoked once for each key-value pair
218+
* @param {object} [obj] - object to map keys, not accepted if being used directly on Object.prototype
219+
* @param {mapKeysCallback} callback - function that produces the new key for the new mapped object
184220
* @param {*} [thisArg] - optional. context to bind to callback
221+
* @returns {object} newly created object with mapped keys
185222

186223
```js
187-
var forEach = require('object-loops/for-each')
224+
var mapKeys = require('object-loops/map-keys')
188225

189226
var obj = {
190227
foo: 10,
191228
bar: 20,
192229
baz: 30
193230
}
194-
var keyConcat = ''
195-
var valSum = 0
196-
forEach(obj, function (val, key, obj) {
197-
keyConcat += key
198-
valSum += val
231+
var mappedObj = mapKeys(obj, function (key, val, obj) {
232+
return key + 'New'
199233
})
200-
keyConcat // = 'foobarbaz'
201-
valSum // = 60
234+
mappedObj /* Each key is concated w/ 'New'
235+
{
236+
fooNew: 10,
237+
barNew: 20,
238+
bazNew: 30
239+
}
240+
*/
202241
```
203242

204243
## map

index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ module.exports = extendObjectPrototype
1616
function extendObjectPrototype (hideWarnings) {
1717
[
1818
'every',
19+
'inverse',
1920
'filter',
20-
'find',
2121
'findKey',
22+
'find',
2223
'forEach',
23-
'map',
2424
'mapKeys',
25+
'map',
2526
'reduce',
2627
'some'
2728
].forEach(function (methodName) {

inverse.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @module object-loops/inverse
3+
*/
4+
var isInteger = require('101/is-integer')
5+
var reduce = require('./reduce')
6+
7+
/**
8+
* Creates a new object with keys and values swapped.
9+
* @function module:object-loops/inverse
10+
* @param {object} [obj] - object to inverse keys and values, not accepted if being used directly on Object.prototype
11+
* @returns {object} newly created object with inverseped values
12+
*/
13+
module.exports = inverse
14+
15+
function inverse (obj) {
16+
if (Array.isArray(obj)) {
17+
var valsAreInts = obj.every(isInteger)
18+
return obj.reduce(flip, valsAreInts ? [] : {})
19+
}
20+
if (typeof obj !== 'object' && typeof obj !== 'function') {
21+
throw new TypeError(obj + ' must be an object')
22+
}
23+
return reduce(obj, flip, {})
24+
}
25+
26+
function flip (inversed, val, key) {
27+
inversed[val] = key
28+
return inversed
29+
}

test/fixtures/reset-object-prototype.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var methodNames = [
22
'every',
3+
'inverse',
34
'filter',
45
'find',
56
'findKey',

test/test-inverse.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
var Code = require('code')
2+
var Lab = require('lab')
3+
var lab = exports.lab = Lab.script()
4+
5+
var describe = lab.describe
6+
var it = lab.it
7+
var before = lab.before
8+
var after = lab.after
9+
var expect = Code.expect
10+
11+
var inverse = require('../inverse')
12+
13+
describe('inverse', function () {
14+
describe('prototype', function () {
15+
before(function (done) {
16+
require('../index')()
17+
done()
18+
})
19+
after(require('./fixtures/reset-object-prototype'))
20+
it('should iterate through all the key-value pairs in the object', function (done) {
21+
var obj = {
22+
foo: 1,
23+
bar: 2,
24+
baz: 3
25+
}
26+
var ret = obj.inverse()
27+
expect(ret).to.deep.equal({
28+
'1': 'foo',
29+
'2': 'bar',
30+
'3': 'baz'
31+
})
32+
done()
33+
})
34+
})
35+
describe('require', function () {
36+
it('should iterate through all the key-value pairs in the object', function (done) {
37+
var obj = {
38+
foo: 1,
39+
bar: 2,
40+
baz: 3
41+
}
42+
var ret = inverse(obj)
43+
expect(ret).to.deep.equal({
44+
'1': 'foo',
45+
'2': 'bar',
46+
'3': 'baz'
47+
})
48+
done()
49+
})
50+
it('should iterate through all the key-value pairs in an array (integer values)', function (done) {
51+
var arr = [
52+
2,
53+
4,
54+
6
55+
]
56+
var ret = inverse(arr)
57+
expect(ret).to.deep.equal([
58+
undefined,
59+
undefined,
60+
0,
61+
undefined,
62+
1,
63+
undefined,
64+
2
65+
])
66+
done()
67+
})
68+
it('should iterate through all the key-value pairs in an array (non-integer values)', function (done) {
69+
var arr = [
70+
2,
71+
'yo',
72+
6
73+
]
74+
var ret = inverse(arr)
75+
expect(ret).to.deep.equal({
76+
'2': 0,
77+
'yo': 1,
78+
'6': 2
79+
})
80+
done()
81+
})
82+
describe('errors', function () {
83+
it('should throw an error if obj must be an object', function (done) {
84+
var obj = 'notObject'
85+
var fn = inverse.bind(null, obj)
86+
expect(fn).to.throw(/must be an object/)
87+
done()
88+
})
89+
})
90+
})
91+
})

0 commit comments

Comments
 (0)