Mapping an array of functions over an array in Javascript - Stack Overflow

I often need to map a list of functions (processors) to several arrays(channels) of float data) so I ha

I often need to map a list of functions (processors) to several arrays(channels) of float data) so I have written a helper function...

const mapMany = function(processors, channels){
  processors.forEach( function(processor){
    channels = channels.map( (channel) => channel.map(processor) );
  });
  return channels;
};

This reads OK (to me at least!) but mapping an array of functions over another array seems like such a generic thing I can't help but wonder if it IS "a thing" already i.e. is there a better / built in / canonical way of implementing this "Map Many" type functionality and if so what is the proper name for it?

I often need to map a list of functions (processors) to several arrays(channels) of float data) so I have written a helper function...

const mapMany = function(processors, channels){
  processors.forEach( function(processor){
    channels = channels.map( (channel) => channel.map(processor) );
  });
  return channels;
};

This reads OK (to me at least!) but mapping an array of functions over another array seems like such a generic thing I can't help but wonder if it IS "a thing" already i.e. is there a better / built in / canonical way of implementing this "Map Many" type functionality and if so what is the proper name for it?

Share Improve this question asked Jan 24, 2017 at 15:12 Roger HeathcoteRoger Heathcote 3,5554 gold badges38 silver badges48 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

Yes, there is a better approach for implementing this. Don't use forEach!

function mapMany(processors, channels) {
    return processors.reduce((channels, processor) =>
        channels.map(channel => channel.map(processor))
    , channels);
}

But no, there is no builtin for this nor a canonical name for it. It's a quite specific function, which can however be trivially posed of the standard building blocks.

I think you are looking for pose. It looks something like this:

const pose = function (...fns) {
    const rest = fns.reverse();
    const first = rest.shift();
    return function (...args) {
        return rest.reduce((acc, f)=>f.call(this, acc), first.apply(this, args));
    };
};

Now you can pose functions like this:

const stringDouble = pose(String, x=>x*2);
stringDouble("44"); //==> "88"

["22","33","44"].map(stringDouble);
//=> ["44", "66", "88"]

And in your case you can write your function like this:

const mapMany = function(processors, channels){
  // pose iterates from last to first so i apply reverse
  const fun = pose.apply(undefined, processors.reverse());
  return channels.map(fun);
}; 

The advantage over your own code and the other answer using reduce is that this does not make processors.length arrays in the process but just the one.

There are libraries that supplies pose. It's a mon function in functional programming.

Other mapping functions like the ones in Underscore lets you set this. Then class methods will work as I pass this to the underlying functions as well.

So as Bergi points out it was simply reduce I was looking for, splitting it into two functions makes it much clearer...

const applySingleProcessor = function(channels, processor){
  return channels.map( channel => channel.map(processor) );
};

const applyMultipleProcessors = function(processors, channels) {
  return processors.reduce(applySingleProcessor, channels);
};

Yay simplicity!

While I would normally use .reduce() as @Bergi did, just for a variety here is a simple recursive .map() solution without .reduce();

var channels = [[1,2,3,4],[5,6,7,8], [857,1453,1881,1071]],
  processors = [x => x+1, x => x*x, x => Math.sqrt(x), x => x-1],
     mapMany = (processors, channels) => processors.length ? (channels = channels.map(c => c.map(processors[0])),
                                                              mapMany(processors.slice(1),channels))
                                                           : channels;
console.log(mapMany(processors,channels));

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745389024a4625573.html

相关推荐

  • Mapping an array of functions over an array in Javascript - Stack Overflow

    I often need to map a list of functions (processors) to several arrays(channels) of float data) so I ha

    3小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信