Given the following arrays:
const array1 = ["a1", "b1", "c1", "d1"],
array2 = ["a2", "b2"],
array3 = ["a3", "b3", "c3"]
Is there any ramda function to simplify the following scenario on which I could give one or more arrays?
const nestedMap = map => {
const result = []
for(let item1 of array1)
for(let item2 of array2)
for(let item3 of array3)
result.push(map(item1, item2, item3))
return result
}
Whole function would look as follows:
// Sample usage
nestedMap((item1, item2, item3) => `${item1} ${item2} ${item3}`, array1, array2, array3)
I'm looking to avoid reinventing the wheel.
Note: Vanilla javascript or any other library can be acceptable. I initially talked about ramda as it has a lot of functions and maybe I've missed which could assist on solving this problem
You can use the applicative instance for arrays here to simply R.lift
your function:
const array1 = ["a1", "b1", "c1", "d1"],
array2 = ["a2", "b2"],
array3 = ["a3", "b3", "c3"]
const nestedMap = R.lift((item1, item2, item3) => `${item1} ${item2} ${item3}`)
console.log(nestedMap(array1, array2, array3))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
Ramda has a xprod
function that gives the cross-product of two lists. It's relatively straightforward to extend it to multiple lists like this:
const xproduct = R.reduce(R.pipe(R.xprod, R.map(R.unnest)), [[]])
Then we can use this to create the nested map function relatively easily:
const array1 = ["a1", "b1", "c1", "d1"],
array2 = ["a2", "b2"],
array3 = ["a3", "b3", "c3"]
const xproduct = R.reduce(R.pipe(R.xprod, R.map(R.unnest)), [[]])
const nestedMap = (fn, ...arrs) => R.map(R.apply(fn), xproduct(arrs))
console.log(nestedMap((a, b, c) => `${a}-${b}-${c}`, array1, array2, array3))
//==> ["a1-a2-a3", "a1-a2-b3", ...]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
You could use a two step approach,
const
nestedMap = (fn, ...array) => array
.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []))
.map(a => fn(...a)),
array1 = ["a1", "b1", "c1", "d1"],
array2 = ["a2", "b2"],
array3 = ["a3", "b3", "c3"],
result = nestedMap((item1, item2, item3) => `${item1} ${item2} ${item3}`, array1, array2, array3)
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With