使用 Ramda 简化数组计算
Simplifying calculation of arrays with Ramda
我想这样计算三个数组。
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = zipWith (add, (zipWith (multiply, Data.x, Data.y)), Data.z)
console.log(XtimesYplusZ);//[25,45,65]
这段代码工作正常,但在可读性方面不是很好。
所以,现在我创建了以后可以应用的计算模式:
const calc1 = ({x, y, z}) => x * y + z
console.log(calc1(Data)); //ERROR
这是行不通的。我有很多不同的模式,例如 ({x, y, z}) => x / y - z
、({x, y, z}) => (x + y) * z
等等。像这样的数组的标准计算方法是什么?
在这个例子中:
const calc1 = ({x, y, z}) => x * y + z
console.log(calc1(Data)); //ERROR
您正在尝试对数组进行加法和乘法运算,而不是数组的项。
使用 R.zipWith 效果不佳,因为它需要实际数组,并且一次只能压缩 2 个数组。
一个更简单的解决方案是使用 R.props 获取 sub-arrays,转置它们 ([[2, 10, 5], [4, 10, 5]]...
),然后使用 calc
函数映射和合并这些值(我用数组解构替换了对象解构):
const { pipe, props, transpose, map } = R
const calc = ([x, y, z]) => x * y + z
const fn = pipe(props(['x', 'y', 'z']), transpose, map(calc))
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = fn(Data)
console.log(XtimesYplusZ) // [25,45,65]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
此示例展示了 Scott 关于提取 R.transpose 和 R.map 的组合以创建 zipAllWith
函数的建议:
const { curry, map, apply, transpose, pipe, props } = R
const zipAllWith = curry((fn, xss) => map(apply(fn), transpose(xss)));
const fn = pipe(props(['x', 'y', 'z']), zipAllWith((x, y, z) => x * y + z))
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = fn(Data)
console.log(XtimesYplusZ) // [25,45,65]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
我想这样计算三个数组。
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = zipWith (add, (zipWith (multiply, Data.x, Data.y)), Data.z)
console.log(XtimesYplusZ);//[25,45,65]
这段代码工作正常,但在可读性方面不是很好。 所以,现在我创建了以后可以应用的计算模式:
const calc1 = ({x, y, z}) => x * y + z
console.log(calc1(Data)); //ERROR
这是行不通的。我有很多不同的模式,例如 ({x, y, z}) => x / y - z
、({x, y, z}) => (x + y) * z
等等。像这样的数组的标准计算方法是什么?
在这个例子中:
const calc1 = ({x, y, z}) => x * y + z
console.log(calc1(Data)); //ERROR
您正在尝试对数组进行加法和乘法运算,而不是数组的项。
使用 R.zipWith 效果不佳,因为它需要实际数组,并且一次只能压缩 2 个数组。
一个更简单的解决方案是使用 R.props 获取 sub-arrays,转置它们 ([[2, 10, 5], [4, 10, 5]]...
),然后使用 calc
函数映射和合并这些值(我用数组解构替换了对象解构):
const { pipe, props, transpose, map } = R
const calc = ([x, y, z]) => x * y + z
const fn = pipe(props(['x', 'y', 'z']), transpose, map(calc))
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = fn(Data)
console.log(XtimesYplusZ) // [25,45,65]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
此示例展示了 Scott 关于提取 R.transpose 和 R.map 的组合以创建 zipAllWith
函数的建议:
const { curry, map, apply, transpose, pipe, props } = R
const zipAllWith = curry((fn, xss) => map(apply(fn), transpose(xss)));
const fn = pipe(props(['x', 'y', 'z']), zipAllWith((x, y, z) => x * y + z))
const Data = {
x : [2,4,6],
y : [10,10,10],
z : [5,5,5]
}
const XtimesYplusZ = fn(Data)
console.log(XtimesYplusZ) // [25,45,65]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>