I am trying to find index of all the instances let's say Header
and Footer
in an array.
var arr = [
'data',
'data',
'data',
'data',
'Header',
'data',
'data',
'data',
'Footer',
'data',
'Header',
'data',
'Footer',
'data'
];
I know how to do this in plain JS (How to find index of all occurrences of element in array?), but I wonder how it would be done in FP, ramda.js
in particular?
I know how to do this for first instance R.findIndex(R.test(_regexForHeader))
but can not wrap my head around looping through all array. Thanks for help.
@pierrebeitz's answer is on point, namely that when you need access to indices while iterating over a list you'll typically zip the list up along with its indices. Ramda provides an R.addIndex function for modifying functions like map
to provide the index along with each element while iterating.
The nesting in his example can also be replaced with a composition pipeline if you prefer:
const zipWithIndex = addIndex(map)(pair);
const isHeaderOrFooter = either(equals('Header'), equals('Footer'));
const hfIndices = pipe(
zipWithIndex,
filter(pipe(head, isHeaderOrFooter)),
map(nth(1))
);
hfIndices(arr);
One thing to be mindful of with both of these approaches is you'll end up iterating over the list multiple times. This won't typically be a problem for a small list, however for larger lists you might want to consider using R.into which effectively fuses the maps and filter together into a transducer that will now take only a single pass over the list (see http://simplectic.com/blog/2015/ramda-transducers-logs/ for a good intro to transducers).
This can be achieved with a small tweak to hfIndices
in the above example by swapping the composition from pipe
to compose
(transducer functions compose in the opposite order) and wrapping it with into
.
const hfIndices = into([], compose(
zipWithIndex,
filter(pipe(head, isHeaderOrFooter)),
map(nth(1))
));
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments