Nested FP Array Map

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 in 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
}

The whole function will look like this:

// Sample usage
nestedMap((item1, item2, item3) => `${item1} ${item2} ${item3}`, array1, array2, array3)

I want to avoid wheel reuse.

Note. Vanilla javascript or any other library may be acceptable. I initially talked about ramda, since it has many functions, and maybe I missed that could help in solving this problem.

+4
source share
4 answers

You can use the applicative instance for arrays here, just R.liftyour 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>
Run codeHide result
+5
source

Ramda xprod, . , :

const xproduct = R.reduce(R.pipe(R.xprod, R.map(R.unnest)), [[]])

:

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>
Hide result
+3

,

  • .

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; }
Hide result
+2

, @ScottChristopher, .ap ( .chain), Array - ! , ...

The idea here demonstrates the behavior / output of the target in a piece of code that shows you all the moving parts at once. With only ~ 8 lines of code to understand, the intimidation factor is pretty low; compared to something like digging at the source of the Ramba (which is actually quite nice)

I recently shared another answer that does something very similar, using delimited sequels - if you are interested in this answer, I think you will also like this reading, _ ^

// Array Applicative  
Array.prototype.ap = function (...args)
  {
    const loop = (acc, [x,...xs]) =>
      x === undefined
        ? [ this [0] (...acc) ]
        : x.chain (a =>
            loop (acc.concat ([a]), xs))
    return loop ([], args)
  }
 
// Array Monad
Array.prototype.chain = function chain (f)
  {
    return this.reduce ((acc, x) =>
      acc.concat (f (x)), [])
  }

const array1 = ['a1', 'b1', 'c1', 'd1']
const array2 = ['a2', 'b2']
const array3 = ['a3', 'b3', 'c3']

console.log ([ (x,y,z) => [x,y,z] ] .ap (array1, array2, array3))
// [ [ 'a1', 'a2', 'a3' ],
//   [ 'a1', 'a2', 'b3' ],
//   [ 'a1', 'a2', 'c3' ],
//   [ 'a1', 'b2', 'a3' ],
//   [ 'a1', 'b2', 'b3' ],
//   [ 'a1', 'b2', 'c3' ],
//   [ 'b1', 'a2', 'a3' ],
//   [ 'b1', 'a2', 'b3' ],
//   [ 'b1', 'a2', 'c3' ],
//   [ 'b1', 'b2', 'a3' ],
//   [ 'b1', 'b2', 'b3' ],
//   [ 'b1', 'b2', 'c3' ],
//   [ 'c1', 'a2', 'a3' ],
//   [ 'c1', 'a2', 'b3' ],
//   [ 'c1', 'a2', 'c3' ],
//   [ 'c1', 'b2', 'a3' ],
//   [ 'c1', 'b2', 'b3' ],
//   [ 'c1', 'b2', 'c3' ],
//   [ 'd1', 'a2', 'a3' ],
//   [ 'd1', 'a2', 'b3' ],
//   [ 'd1', 'a2', 'c3' ],
//   [ 'd1', 'b2', 'a3' ],
//   [ 'd1', 'b2', 'b3' ],
//   [ 'd1', 'b2', 'c3' ] ]
Run codeHide result
+1
source

Source: https://habr.com/ru/post/1687227/


All Articles