2

我试图在一个数组Header中找到所有实例的索引。Footer

var arr = [
'data',
'data',
'data',
'data',
'Header',
'data',
'data',
'data',
'Footer',
'data',
'Header',
'data',
'Footer',
'data'
];

我知道如何在普通 JS 中做到这一点(如何找到数组中所有出现的元素的索引?),但我想知道在 FP 中如何做到这一点,ramda.js特别是?

我知道如何在第一个实例中执行此操作,R.findIndex(R.test(_regexForHeader))但不能绕着循环遍历所有数组。感谢帮助。

4

2 回答 2

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))
));
于 2016-03-20T11:30:27.257 回答
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]

这不是最复杂的解决方案,但它应该能让你前进!

于 2016-03-20T10:59:07.543 回答