Dado que estas declaraciones de funciones existen dentro del alcance:
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); } } }Teniendo esta función de devolución de llamada como ejemplo:
function cb(x, y) { console.log(x); console.log(y); } ¿Es posible usar técnicas de FP (como el enlace de argumentos, la composición y la aplicación parcial) para aplicar la función de devolución de llamada a 2 matrices de longitud arbitraria? Por ejemplo: ["foo", "bar", "baz", "quux"] y [12, 42] ? La salida esperada en este caso sería:
foo 12 foo 42 bar 12 bar 42 baz 12 ...and so on Dado que Array.prototype.forEach y Array.prototype.map pasan 3 argumentos a la función de devolución de llamada, al menos es posible iterar sobre una sola matriz usando la composición de funciones de la siguiente manera:
["foo", "bar", "baz", "quux"].forEach(compose(cb, id))También es posible mapear una matriz en funciones aplicadas parcialmente de esta manera:
[12, 42].map(compose(partial(cb), id)) He estado buscando usar Function.prototype.apply , Function.prototype.bind y Function.prototype.call , combinándolos con Array.prototype.forEach y Array.prototype.map , hasta ahora sin éxito. Estoy tratando de no introducir más declaraciones/expresiones de funciones.
Gracias a Mulan, el problema se puede resolver dividiéndolo en la parte que calcula el producto cartesiano de listas y aplicando la lista resultante a una función determinada.
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));Creo que podría estar haciendo más trabajo para usted mismo al forzar la compose y partial donde no son particularmente útiles. Parece que está buscando calcular un product de matrices de entrada. El resultado es una matriz de productos, cada uno de los cuales contiene una agrupación única de elementos tomados de las matrices de entrada:
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; } Si realmente desea usar partial , puede aceptar una devolución de llamada cb como primer argumento y luego todas las matrices para multiplicar a partir de entonces. Cada paso en product aplica un argumento a cb . El resultado es una matriz de productos donde cada producto es una matriz de funciones parcialmente aplicadas, que se pueden ejecutar llamando a 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; }