Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

122
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda