-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
`toObject` is also now implemented by using `toObjectWith` with an identity function.
- Loading branch information
Showing
3 changed files
with
108 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import reduce from './reduce' | ||
import getType from './get-type' | ||
import isPrimitive from './is-primitive' | ||
|
||
export default function toObjectWith (value, fn) { | ||
const fnType = getType(fn) | ||
if (fnType !== 'function') { | ||
throw new TypeError(`Expected a function, got ${fnType}`) | ||
} | ||
|
||
if (isPrimitive(value)) return { [value]: fn(value) } | ||
|
||
let inputType = getType(value) | ||
if (inputType === 'object') return value | ||
|
||
if (inputType === 'map' || inputType === 'set') { | ||
inputType = 'array' | ||
value = Array.from(value) | ||
} | ||
|
||
if (inputType !== 'array') return {} | ||
|
||
return reduce(value, (acc, key) => { | ||
if (Array.isArray(key) && key.length === 2) { | ||
return Object.assign(acc, { [key[0]]: fn(key[1]) }) | ||
} | ||
|
||
return Object.assign(acc, { [key]: fn(key) }) | ||
}, {}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,5 @@ | ||
import reduce from './reduce' | ||
import getType from './get-type' | ||
import isPrimitive from './is-primitive' | ||
import toObjectWith from './to-object-with' | ||
|
||
export default function toObject (value) { | ||
if (isPrimitive(value)) return { [value]: value } | ||
|
||
let inputType = getType(value) | ||
if (inputType === 'object') return value | ||
|
||
if (inputType === 'map' || inputType === 'set') { | ||
inputType = 'array' | ||
value = Array.from(value) | ||
} | ||
|
||
if (inputType !== 'array') return {} | ||
|
||
return reduce(value, (acc, key) => { | ||
if (Array.isArray(key) && key.length === 2) { | ||
return Object.assign(acc, { [key[0]]: key[1] }) | ||
} | ||
|
||
return Object.assign(acc, { [key]: key }) | ||
}, {}) | ||
return toObjectWith(value, v => v) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import test from 'ava' | ||
import fn from '../prod/to-object-with' | ||
|
||
const run = (expectedValues, input = expectedValues) => { | ||
const results = [] | ||
|
||
const callback = value => { | ||
results.push(expectedValues.includes(value)) | ||
return value | ||
} | ||
|
||
fn(input, callback) | ||
|
||
return results.every(Boolean) | ||
} | ||
|
||
test('array: callback receives each element', t => { | ||
t.true(run(['one', 'two', 'three'])) | ||
}) | ||
|
||
test('primitive: callback receives the primitive', t => { | ||
t.true(run([3], 3)) | ||
t.true(run([true], true)) | ||
t.true(run(['fly'], 'fly')) | ||
t.true(run([null], null)) | ||
t.true(run([undefined], undefined)) | ||
}) | ||
|
||
test('object: callback receives each value', t => { | ||
t.true(run(['cool'], { ultra: 'cool' })) | ||
}) | ||
|
||
test('array: callback receives value of object entry-like elements', t => { | ||
const input = [['keyOne', 1], ['keyTwo', 2], ['keyThree', 3]] | ||
t.true(run([1, 2, 3], input)) | ||
}) | ||
|
||
test('map: callback receives each element', t => { | ||
const input = new Map([['keyOne', 1], ['keyTwo', 2], ['keyThree', 3]]) | ||
t.true(run([1, 2, 3], input)) | ||
}) | ||
|
||
test('set: callback receives each element', t => { | ||
const input = new Set(['one', 'two', 'three']) | ||
t.true(run(['one', 'two', 'three'], input)) | ||
}) | ||
|
||
test('returns an empty object for unhandled types', t => { | ||
t.throws(() => fn('input'), TypeError) | ||
}) | ||
|
||
test('allows for transforming values of the resulting object', t => { | ||
const input = new Set(['one', 'two', 'three', 'four', 'five']) | ||
|
||
const callback = value => { | ||
switch (value) { | ||
case 'one': return 1 | ||
case 'two': return 2 | ||
case 'three': return 3 | ||
case 'four': return 4 | ||
case 'five': return 5 | ||
} | ||
} | ||
|
||
const actual = fn(input, callback) | ||
|
||
const expected = { | ||
one: [1], | ||
two: [2], | ||
three: [3], | ||
four: [4], | ||
five: [5] | ||
} | ||
|
||
t.deepEqual(actual, expected) | ||
}) |