Skip to content

Instantly share code, notes, and snippets.

@mLuby
Created February 21, 2017 10:20
Show Gist options
  • Save mLuby/d261360b7b72475d6b4d6f53fb5e1919 to your computer and use it in GitHub Desktop.
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
// 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