Ramda 在一个循环中映射和过滤
Ramda map and filter in one loop
const R = require('rambda')
export const test = () => {
const data = [1, 2, 3, 4, 5, 6, 7, 8]
const filter = no => no > 5
const map = no => no * 100
// looping 2 times
return data
.filter(filter)
.map(map)
// wird 1 loop
return data.reduce((data, no) => {
if (!filter(no)) return data
data.push(map(no))
return data
}, [])
// I want to do something like this.
return data.map(R.pipe(map, filter))
}
您好,请问是否可以使用ramda或rambda在一个循环中进行映射和过滤?
我的例子:
return data.map(R.pipe(map, filter))
回来了
Array [
600,
700,
800,
true,
true,
true,
true,
true,
true,
true,
true,
]
我需要它是 [600, 700, 800]
当然可以。
const expr = R.compose(
R.map(x => x * 100),
R.filter(x => x > 5)
);
const result = expr([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(result);
更新:one-loop方式:
const iter = (acc, x) => (x > 5 && acc.push(x * 100), acc)
const result = R.reduce(iter, [], [1, 2, 3, 4, 5, 6, 7, 8])
无论是one-loop还是two-loop,执行相同的逻辑,应该没有区别。
你可以用 Ramda 的 transducers 来做到这一点。
(免责声明:我是 Ramda 作者)
虽然常规 Ramda 函数的正常组合会针对每个列表转换进行循环,但转换后的函数会 运行 每次迭代时组合中的每个函数。请注意,由于技术原因,使用换能器时,成分 运行 的顺序相反。
并非每个函数都是转换器。文档使用这个注释来表示一个:"Acts as a transducer if a transformer is given in list position."这两个都包含map
and filter
. There are several functions that make it easier to work with transducers. into
是其中之一。
不过,编写您自己的 filterMap
函数可能更容易。不难:
const filterMap = curry((f, m, data) => reduce(
(a, i) => f(i) ? append(m(i), a) : a,
[], data))
const {compose, map, filter, into, curry, reduce, append} = R;
const data = [1, 2, 3, 4, 5, 6, 7, 8]
const gt5 = no => {console.log(`filter: ${no}`); return no > 5;}
const times100 = no => {console.log(`map ${no}`); return no * 100;}
console.log('========= Plain composition =========')
const transform1 = compose(map(times100), filter(gt5))
console.log(transform1(data))
console.log('========== With transducers =========')
const transform2 = into([], compose(filter(gt5), map(times100)));
console.log(transform2(data))
console.log('=========== With filterMap ==========')
const filterMap = curry((f, m, data) => reduce((a, i) => f(i) ? append(m(i), a) : a, [], data))
console.log(filterMap(gt5, times100)(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
如果你想看看换能器是如何发光的,请在合成的末尾添加一个take(2)
。
这些给 Ramda 的实现增加了很大的复杂性,并且有人讨论要删除它们,或者试图找到一种方法使它们成为可选的。但是在这方面没有做太多。
const R = require('rambda')
export const test = () => {
const data = [1, 2, 3, 4, 5, 6, 7, 8]
const filter = no => no > 5
const map = no => no * 100
// looping 2 times
return data
.filter(filter)
.map(map)
// wird 1 loop
return data.reduce((data, no) => {
if (!filter(no)) return data
data.push(map(no))
return data
}, [])
// I want to do something like this.
return data.map(R.pipe(map, filter))
}
您好,请问是否可以使用ramda或rambda在一个循环中进行映射和过滤?
我的例子:
return data.map(R.pipe(map, filter))
回来了
Array [
600,
700,
800,
true,
true,
true,
true,
true,
true,
true,
true,
]
我需要它是 [600, 700, 800]
当然可以。
const expr = R.compose(
R.map(x => x * 100),
R.filter(x => x > 5)
);
const result = expr([1, 2, 3, 4, 5, 6, 7, 8]);
console.log(result);
更新:one-loop方式:
const iter = (acc, x) => (x > 5 && acc.push(x * 100), acc)
const result = R.reduce(iter, [], [1, 2, 3, 4, 5, 6, 7, 8])
无论是one-loop还是two-loop,执行相同的逻辑,应该没有区别。
你可以用 Ramda 的 transducers 来做到这一点。
(免责声明:我是 Ramda 作者)
虽然常规 Ramda 函数的正常组合会针对每个列表转换进行循环,但转换后的函数会 运行 每次迭代时组合中的每个函数。请注意,由于技术原因,使用换能器时,成分 运行 的顺序相反。
并非每个函数都是转换器。文档使用这个注释来表示一个:"Acts as a transducer if a transformer is given in list position."这两个都包含map
and filter
. There are several functions that make it easier to work with transducers. into
是其中之一。
不过,编写您自己的 filterMap
函数可能更容易。不难:
const filterMap = curry((f, m, data) => reduce(
(a, i) => f(i) ? append(m(i), a) : a,
[], data))
const {compose, map, filter, into, curry, reduce, append} = R;
const data = [1, 2, 3, 4, 5, 6, 7, 8]
const gt5 = no => {console.log(`filter: ${no}`); return no > 5;}
const times100 = no => {console.log(`map ${no}`); return no * 100;}
console.log('========= Plain composition =========')
const transform1 = compose(map(times100), filter(gt5))
console.log(transform1(data))
console.log('========== With transducers =========')
const transform2 = into([], compose(filter(gt5), map(times100)));
console.log(transform2(data))
console.log('=========== With filterMap ==========')
const filterMap = curry((f, m, data) => reduce((a, i) => f(i) ? append(m(i), a) : a, [], data))
console.log(filterMap(gt5, times100)(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
如果你想看看换能器是如何发光的,请在合成的末尾添加一个take(2)
。
这些给 Ramda 的实现增加了很大的复杂性,并且有人讨论要删除它们,或者试图找到一种方法使它们成为可选的。但是在这方面没有做太多。