我正在尝试查找所有实例的索引,让我们在数组中说Header
和Footer
。
var arr = [
'data',
'data',
'data',
'data',
'Header',
'data',
'data',
'data',
'Footer',
'data',
'Header',
'data',
'Footer',
'data'
];
我知道如何在普通的JS(How to find index of all occurrences of element in array?)中做到这一点,但我想知道如何在FP中完成它,特别是ramda.js
?
我知道如何为第一个实例R.findIndex(R.test(_regexForHeader))
执行此操作,但无法绕过循环遍历所有数组。感谢帮助。
答案 0 :(得分:3)
@ pierrebeitz的答案很明确,即当您在迭代列表时需要访问索引时,您通常会将列表与其索引一起压缩。 Ramda提供R.addIndex函数来修改map
之类的函数,以便在迭代时提供索引以及每个元素。
如果你愿意,他的例子中的嵌套也可以用合成管道替换:
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);
使用这两种方法时要注意的一件事是,您最终会多次迭代列表。对于小型列表,这通常不会成为问题,但是对于较大的列表,您可能需要考虑使用R.into来有效地融合地图并一起过滤成一个传感器,现在只需要一次通过列表(参见http://simplectic.com/blog/2015/ramda-transducers-logs/了解传感器的简介)。
通过将组合从hfIndices
交换到pipe
(换能器函数以相反的顺序组成)并将其包裹起来,可以通过对上面示例中compose
的小调整来实现这一点。 into
。
const hfIndices = into([], compose(
zipWithIndex,
filter(pipe(head, isHeaderOrFooter)),
map(nth(1))
));
答案 1 :(得分:0)
我不是因为FP,但我相信你必须"生成"您要使用的数据。你必须添加一个索引,然后再应用你的过滤器:
var arr = ['data', 'data', 'data', 'data', 'Header', 'data', 'data', 'data', 'Footer', 'data', 'Header', 'data', 'Footer', 'data'];
R.map((e) => e[1],
R.filter(val => val[0] == 'Header' || val[0] == 'Footer',
R.addIndex(R.map)((e, i) => [e,i], arr)
)
);
// => [4, 8, 10, 12]
这不是最精细的解决方案,但它应该让你去!