简体   繁体   中英

Functional way to execute a sub-array with Ramda

Is there a more functional way of doing the below, perhaps with Ramda?

var time = 100;

sequenceInstruments.forEach(function(instrument){
    if(instrument.on)
    {
       playInstrument(time, instrument.duration);
    }
})

By only utilising functions from Ramda in a point-free manner your example would look something like this.

const play = R.forEach(R.when(R.prop('on'),
                              R.compose(R.partial(playInstrument, [time]),
                                        R.prop('duration'))))
play(sequenceInstruments)

However I often think it can be better to dial it back a little, where the use of an anonymous function could perhaps make the code more readable and convey the intent more clearly.

const play = R.forEach(R.when(R.prop('on'), i => playInstrument(time, i.duration)))

play(sequenceInstruments)

While I agree with Scott Christopher that the point-ful solution is easier to understand than any points-free version you're likely to come up with, if you are interested in developing a point-free version, and if you'd like time to be a parameter to your final function, Ramda offers a function that might help, useWith . (There's also a related function, converge useful for slightly different circumstances.) This depends upon your playInstrument function being curried:

const play = R.useWith(R.forEach, [
  playInstrument, 
  R.compose(R.pluck('duration'), R.filter(R.prop('on')))
]);

play(100, sequenceInstruments);

You can see this in action on the Ramda REPL .

I agree with @ftor: filter will allow you to compose in a more linear fashion, which leads to totally readable point-free code.

const play = pipe(
    filter(prop('on')),           // take only the instruments that are 'on'
    map(prop('duration')),        // take the duration of each of those
    forEach(playInstrument(100))  // play'm all
);

play(sequenceInstruments);

This is assuming playInstruments is curried already.

With lodash/fp 's shorthands you could even do this:

const play = pipe(
    filter('on'),
    map('duration'),   
    forEach(playInstrument(100))
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM