使用 ramda 将数组数组转换为数组对象

Convert array of arrays to object of arrays, using ramda

给定一个 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 数据,表现符合预期。我已经使用 pipeassoc 进行了探索,但到目前为止还没有成功。

使用 Ramda,您可以 Transpose the array of arrays, and then use 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() instead of R.transpose, and pick keys with values using _.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>

第一,transpose the input and then 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>