如何找到数组中所有元素出现的索引(Ramda.js方式)?

时间:2016-03-20 10:23:15

标签: javascript arrays ramda.js

我正在尝试查找所有实例的索引,让我们在数组中说HeaderFooter

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))执行此操作,但无法绕过循环遍历所有数组。感谢帮助。

2 个答案:

答案 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]

这不是最精细的解决方案,但它应该让你去!