Created
February 21, 2017 10:20
-
-
Save mLuby/d261360b7b72475d6b4d6f53fb5e1919 to your computer and use it in GitHub Desktop.
create all variants of an object given an object whose keys have arrays of values
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
// point-free version | |
function combos (obj) { | |
return Object.keys(obj).reduce((results, key) => (Array.isArray(obj[key]) ? obj[key] : [obj[key]]).map(value => results.map(result => Object.assign({}, result, {[key]: value}))).reduce((flattened, list) => [...flattened, ...list]), [{}]) | |
} | |
test(combos({x: 1, y: [2, 3]}), [{x: 1, y: 2}, {x: 1, y: 3}]) | |
test(combos({x: [1, 2], y: 3}), [{x: 1, y: 3}, {x: 2, y: 3}]) | |
test(combos({x: [1, 2], y: [4, 5], z: 7}), [{x: 1, y: 4, z: 7}, {x: 2, y: 4, z: 7}, {x: 1, y: 5, z: 7}, {x: 2, y: 5, z: 7}]) | |
test(combos({x: [1, 2], y: [4, 5]}), [{x: 1, y: 4}, {x: 2, y: 4}, {x: 1, y: 5}, {x: 2, y: 5}]) | |
test(combos({x: [1, 2, 3], y: [4, 5]}), [ | |
{x: 1, y: 4}, | |
{x: 2, y: 4}, | |
{x: 3, y: 4}, | |
{x: 1, y: 5}, | |
{x: 2, y: 5}, | |
{x: 3, y: 5} | |
]) | |
test(combos({x: [1, 2], y: [4, 5, 6]}), [ | |
{x: 1, y: 4}, | |
{x: 2, y: 4}, | |
{x: 1, y: 5}, | |
{x: 2, y: 5}, | |
{x: 1, y: 6}, | |
{x: 2, y: 6} | |
]) | |
// x: [1, 2] -> [{x: 1}, {x: 2}] | |
// given k and [v1, …, vn] | |
// return [{k: v1}, …, {k: vn}] | |
// y: [3, 4] -> y: 3 [{x: 1}, {x: 2}], y: 4 [{x: 1}, {x: 2}] -> | |
// given k, [v1, …, vn], and optional results | |
// for each key | |
// for each result | |
// add key to result | |
// flatten results | |
// non-point-free version | |
// function combos (obj) { | |
// let results = [{}] | |
// const keys = Object.keys(obj) | |
// keys.map(key => { | |
// const values = obj[key] | |
// const resultsWithKey = (Array.isArray(values) ? values : [values]).map(value => { | |
// // for each value make a copy of results and add key/value to each result | |
// const newResults = results.map(result => { | |
// // console.log({key, value, result, newResult: Object.assign({}, result, {[key]: value})}) | |
// return Object.assign({}, result, {[key]: value}) | |
// }) | |
// return newResults | |
// }).reduce((flattened, list) => [...flattened, ...list]) | |
// results = resultsWithKey | |
// }) | |
// return results | |
// } | |
// test([{x: 1, y: 2}, {x: 1, y: 3}], [{x: 1, y: 2}, {x: 1, y: 3}]) | |
function test (actual, expected) { console.log(deepEqual(actual, expected) ? "√" : "X", "\n", actual, "\n", deepEqual(actual, expected) ? "" : expected)} | |
function deepEqual (a, b) { return typeof b === "object" ? Object.keys(b).reduce((t, k) => t && a.hasOwnProperty(k) && deepEqual(a[k], b[k]), true): a === b} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment