Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

123
Vistas
Apply callback to 2 arbitrary length arrays using functional programming in JavaScript

Given that these function declarations exist within scope:

function compose() {
  var funcs = arguments;

  return function() {
    var args, i;

    args = arguments;

    for (i = funcs.length - 1; i >= 0; i--) {
      args = [funcs[i].apply(null, args)];
    }

    return args[0];
  };
}

function id(x) {
  return x;
}

function partial(targetfn) {
  var arity = targetfn.length;

  return function fn() {
    if (arguments.length < arity) {
      return Function.prototype.bind.apply(fn, [null].concat(
        Array.prototype.slice.call(arguments)
      ));
    } else {
      return targetfn.apply(null, arguments);
    }
  }
}

Having this callback function as an example:

function cb(x, y) {
  console.log(x);
  console.log(y);
}

Is it possible using FP techniques (such as argument binding, composition and partial application) to apply the callback function to 2 arrays of arbitrary length? E.g.: ["foo", "bar", "baz", "quux"] and [12, 42]? The expected output in this case would be:

foo
12
foo
42
bar
12
bar
42
baz
12
...and so on

Since Array.prototype.forEach and Array.prototype.map pass 3 arguments to the callback function, it's at least possible to iterate over a single array using function composition as follows:

["foo", "bar", "baz", "quux"].forEach(compose(cb, id))

It's also possible to map an array into partially applied functions like so:

[12, 42].map(compose(partial(cb), id))

I've been looking into using Function.prototype.apply, Function.prototype.bind and Function.prototype.call, combining them with Array.prototype.forEach and Array.prototype.map, so far without success. I'm trying hard not to introduce more function declarations / expressions.

Update

Thanks to Mulan, the problem can be solved by splitting it into the part that computes the cartesian product of lists and applying the resulting list to a given function.

function product() {
  var args = [].slice.call(arguments);

  return args.reduce(function(prev, cur) {
    var ret = [];

    prev.forEach(function(x) {
      cur.forEach(function(y) {
        ret.push(x.concat(y));
      });
    });

    return ret;
  }, args.shift().map(function(val) {
    return [val];
  }));
}

product(
  ["foo", "bar", "baz", "quux"],
  [12, 42]
).forEach(Function.prototype.apply.bind(cb, null));
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I think you might be making more work for yourself by forcing compose and partial where they're not particularly useful. It seems like you're looking to compute a product of input arrays. The result is an array of products, each of which contains a unique grouping of elements taken from the input arrays -

function product(a, ...more) {
  if (more.length == 0)
    return a.map(v => [v])
  else 
    return a.flatMap(v => product(...more).map(p => [v, ...p]))
}

function cb(x,y) {
  console.log(x, y)
}

product(["foo", "bar", "baz", "quux"], [12, 42])
  .forEach(p => cb(...p))
.as-console-wrapper { min-height: 100%; top: 0; }

If you really want to use partial, you can accept a callback cb as the first argument, and then all arrays to multiply thereafter. Each step in product applies one argument to cb. The result is an array of products where each product is an array of partially applied functions, which can be executed by calling cb() -

function partial(f, ...x) {
  return (...y) => f(...x, ...y)
}

function product(cb, a, ...more) {
  if (more.length == 0)
    return a.map(v => partial(cb, v))
  else
    return a.flatMap(v => product(partial(cb, v), ...more))
}

const cb = partial(console.log, "i would like")

const res = product(cb,
  ["🍔", "🌮", "🥪"],
  ["🍟", "🥨"],
  ["🥤", "☕️"]
 )

res.forEach(cb => cb())
.as-console-wrapper { min-height: 100%; top: 0; }

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda