Ramda - 减少组合上的括号嵌套
Ramda - reduce parentheses nesting on composition
我有一个这样的数组:
const arr = [
['1 1 1', '', '2 2 2'],
['', '3 3 3', '4 4 4']
]
我的目标是将它转换成这个数组:
[
[ [1,1,1], [2,2,2] ],
[ [3,3,3], [4,4,4] ]
]
我正在尝试使用函数组合以函数式方式做到这一点。我也在用 Ramda。
我有这个代码
const filterEmpty = filter(o(not, isEmpty));
const getFinalArr = map(
compose( map(map(parseInt)), map(split(' ')), filterEmpty )
)
console.log(getFinalArr(arr))
有没有办法写得少map
嵌套?我试过这样的事情:
const getFinalArr = map(
compose( parseInt, map, map, split(' '), map, filterEmpty )
)
当然没用。
或者,如果有另一种方法可以轻松处理像这样嵌套的数组,我将不胜感激。
你可以用纯 javascript:
const arr = [
['1 1 1', '', '2 2 2'],
['', '3 3 3', '4 4 4']
]
function foo(arr){
// flatten array and remove empty strings
const cleanArray = arr.flat().filter(Boolean)
// convert all strings as independent numbers (["1 1 1"] -> [1,1,1])
const numberArrays = cleanArray.map(suite=> {
return suite.split("").map(Number).filter(Boolean)
})
// batchMemory saves arrays of numbers before saving them
let batchMemory = []
// loop over our array of numbers arrays
return numberArrays.reduce((acc,cur, i)=> {
const index = i+1
// save the current array of number in a temporary memory
batchMemory.push(cur)
// we want to save two arrays of numbers as a single entry in our final result
// so each time the the entry index is a multiple of two,
// we push the two arrays of numbers saved into batchMemory
// in the final result (here the accumulator - acc - of our reducer)
// finally, we clean up batchMemory to repeat the operation with the next arrays of number
if(index %2===0){
acc.push(batchMemory)
batchMemory = []
return acc
}
return acc
}, [])
}
console.log(foo(arr))
您可以使用稍微不同的方法,查看纯 Javascritp 中的解决方案并将其转换为 Ramda。
parse
const
{ compose, filter, isEmpty, map, not, o, split } = R,
array = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']],
resultPure = array.map(a => a
.filter(Boolean)
.map(s => s
.split(' ')
.map(Number)
)
),
fn = map(compose(
map(compose(
map(Number),
split(' ')
)),
filter(o(not, isEmpty))
));
console.log(fn(array));
console.log(resultPure);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
当事情开始变得冗长和混乱时,我更喜欢 R.pipe
on R.compose
,并编写函数,其中每一行代表一个转换:
const { map, pipe, reject, isEmpty, split } = R
const fn = map(pipe(
reject(isEmpty), // remove empty items
map(split(' ')), // convert string to sub-arrays
map(map(Number)), // convert sub-arrays to arrays of numbers
))
const arr = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']]
const result = fn(arr)
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
我也建议考虑递归这种工作
const parse = R.pipe(R.split(' '), R.map(Number));
const normalize = R.pipe(R.reject(R.isEmpty), R.map(parse), R.of);
const fn = ([head, ...tail]) => normalize(head).concat(
tail.length ? fn(tail) : [],
);
// ==
const data = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']]
console.log(
fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
我有一个这样的数组:
const arr = [
['1 1 1', '', '2 2 2'],
['', '3 3 3', '4 4 4']
]
我的目标是将它转换成这个数组:
[
[ [1,1,1], [2,2,2] ],
[ [3,3,3], [4,4,4] ]
]
我正在尝试使用函数组合以函数式方式做到这一点。我也在用 Ramda。
我有这个代码
const filterEmpty = filter(o(not, isEmpty));
const getFinalArr = map(
compose( map(map(parseInt)), map(split(' ')), filterEmpty )
)
console.log(getFinalArr(arr))
有没有办法写得少map
嵌套?我试过这样的事情:
const getFinalArr = map(
compose( parseInt, map, map, split(' '), map, filterEmpty )
)
当然没用。
或者,如果有另一种方法可以轻松处理像这样嵌套的数组,我将不胜感激。
你可以用纯 javascript:
const arr = [
['1 1 1', '', '2 2 2'],
['', '3 3 3', '4 4 4']
]
function foo(arr){
// flatten array and remove empty strings
const cleanArray = arr.flat().filter(Boolean)
// convert all strings as independent numbers (["1 1 1"] -> [1,1,1])
const numberArrays = cleanArray.map(suite=> {
return suite.split("").map(Number).filter(Boolean)
})
// batchMemory saves arrays of numbers before saving them
let batchMemory = []
// loop over our array of numbers arrays
return numberArrays.reduce((acc,cur, i)=> {
const index = i+1
// save the current array of number in a temporary memory
batchMemory.push(cur)
// we want to save two arrays of numbers as a single entry in our final result
// so each time the the entry index is a multiple of two,
// we push the two arrays of numbers saved into batchMemory
// in the final result (here the accumulator - acc - of our reducer)
// finally, we clean up batchMemory to repeat the operation with the next arrays of number
if(index %2===0){
acc.push(batchMemory)
batchMemory = []
return acc
}
return acc
}, [])
}
console.log(foo(arr))
您可以使用稍微不同的方法,查看纯 Javascritp 中的解决方案并将其转换为 Ramda。
parse
const
{ compose, filter, isEmpty, map, not, o, split } = R,
array = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']],
resultPure = array.map(a => a
.filter(Boolean)
.map(s => s
.split(' ')
.map(Number)
)
),
fn = map(compose(
map(compose(
map(Number),
split(' ')
)),
filter(o(not, isEmpty))
));
console.log(fn(array));
console.log(resultPure);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
当事情开始变得冗长和混乱时,我更喜欢 R.pipe
on R.compose
,并编写函数,其中每一行代表一个转换:
const { map, pipe, reject, isEmpty, split } = R
const fn = map(pipe(
reject(isEmpty), // remove empty items
map(split(' ')), // convert string to sub-arrays
map(map(Number)), // convert sub-arrays to arrays of numbers
))
const arr = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']]
const result = fn(arr)
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
我也建议考虑递归这种工作
const parse = R.pipe(R.split(' '), R.map(Number));
const normalize = R.pipe(R.reject(R.isEmpty), R.map(parse), R.of);
const fn = ([head, ...tail]) => normalize(head).concat(
tail.length ? fn(tail) : [],
);
// ==
const data = [['1 1 1', '', '2 2 2'], ['', '3 3 3', '4 4 4']]
console.log(
fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>