使用 ramda 将数组数组转换为数组对象
Posted
技术标签:
【中文标题】使用 ramda 将数组数组转换为数组对象【英文标题】:Convert array of arrays to object of arrays, using ramda 【发布时间】:2021-11-08 12:04:54 【问题描述】:给定一个包含 2d 或 3d 数据的数组。如何创建一个将数据转换为数组对象的函数,其中内部索引分别映射到 x、y 或 z,具体取决于索引是 0、1 还是 2。例如:
// 2d
const inputData2d = [
[-1, 4],
[3, 6],
[9, -8],
]
const outputData2d =
x: [-1, 3, 9],
y: [4, 6, -8],
// 3d
const inputData3d = [
[-1, 4, 5],
[3, 6, 2],
[9, -8, 5],
]
const outputData3d =
x: [-1, 3, 9],
y: [4, 6, -8],
z: [5, 2, 5],
该函数还应该能够处理 2d 和 3d 数据,其行为符合预期。我已经使用pipe
和assoc
进行了探索,但目前还没有运气。
【问题讨论】:
【参考方案1】:使用 Ramda,您可以 Transpose 数组数组,然后使用 R.zipObj 将其与键组合。 R.zipObj 将压缩后的数组截断为两者中较短的一个,因此您可以提供['x', 'y', 'z']
,对于二维数据,它将被截断为['x', 'y']
。
const pipe, transpose, zipObj = R
const fn = pipe(transpose, zipObj(['x', 'y', 'z']))
const inputData2d = [[-1,4],[3,6],[9,-8]]
const inputData3d = [[-1,4,5],[3,6,2],[9,-8,5]]
console.log(fn(inputData2d))
console.log(fn(inputData3d))
<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>
同样的想法也适用于 lodash,尽管它更冗长。您需要使用 _.unzip()
而不是 R.transpose,并使用 _.pickBy()
选择具有值的键:
const flow, unzip, zipObject, pickBy = _
const fn = flow(
unzip,
arr => zipObject(['x', 'y', 'z'], arr),
obj => pickBy(obj)
)
const inputData2d = [[-1,4],[3,6],[9,-8]]
const inputData3d = [[-1,4,5],[3,6,2],[9,-8,5]]
console.log(fn(inputData2d))
console.log(fn(inputData3d))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
您可以使用 Lodash/fp 消除一些冗长的内容:
const flow, unzip, zipObject, pickBy, identity = _
const fn = flow(
unzip,
zipObject(['x', 'y', 'z']),
pickBy(identity)
)
const inputData2d = [[-1,4],[3,6],[9,-8]]
const inputData3d = [[-1,4,5],[3,6,2],[9,-8,5]]
console.log(fn(inputData2d))
console.log(fn(inputData3d))
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
【讨论】:
你打败了我。 我会带你去 lodash 解决方案 :)【参考方案2】:首先,transpose 输入,然后是 zip it into an object。
const matrixToTransposedObject = R.compose(
R.zipObj(["x", "y", "z"]),
R.transpose
);
const inputData2d = [
[-1, 4],
[3, 6],
[9, -8],
];
const outputData2d = matrixToTransposedObject(inputData2d);
console.log(outputData2d);
const inputData3d = [
[-1, 4, 5],
[3, 6, 2],
[9, -8, 5],
];
const outputData3d = matrixToTransposedObject(inputData3d);
console.log(outputData3d);
<script src="https://unpkg.com/ramda@0.27.1/dist/ramda.min.js"></script>
【讨论】:
以上是关于使用 ramda 将数组数组转换为数组对象的主要内容,如果未能解决你的问题,请参考以下文章