对象中的深度展平数组字段

Deep flatten array fields in object

我有一个对象,它有一些字段是数组(字符串或其他对象),我试图将这个对象转换成 csv 但是对于有数组的情况,我希望 csv 去在数组的情况下是垂直的(而不是水平的,索引附加到字段名称)。 在尝试了几个 npm 库和在线转换器后,我无法实现我想要的,带有数组的字段只是用它们的索引作为列名编写。

作为一种解决方法,我现在正在尝试展平对象以充实数组字段,然后将其转换为 csv,但展平仍然保持数组原样,输出中的对象数量没有变化。我尝试了 lodash、underscore、Array's flat 等库,但没有任何效果。

有没有办法通过直接转换为 csv 或至少展平对象来实现这一点。

我手头的实物样本如下

    [
        {
            "field1": "Hello",
            "field2": [
                "list item 1",
                "list item 2",
                "list item 3"
            ],
            "field3": [],
            "field4": [{
                "subfield1": "World",
                "subfield2": "!"
            }, {
                "subfield1": "Again",
                "subfield2": "?"
            }]
        }
    ]

基于这个示例对象,我的输出应该是。

[
    {
        "field1": "Hello",
        "field2": "list item 1",
        "field3": null, // or [], in this case it wouldn't matter
        "field4": {
            "subfield1": "World",
            "subfield2": "!"
        }
    },
    {
        "field1": "Hello",
        "field2": "list item 1",
        "field3": null,
        "field4": {
            "subfield1": "Again",
            "subfield2": "?"
        }
    },
    {
        "field1": "Hello",
        "field2": "list item 2",
        "field3": null,
        "field4": {
            "subfield1": "World",
            "subfield2": "!"
        }
    },
    {
        "field1": "Hello",
        "field2": "list item 2",
        "field3": null,
        "field4": {
            "subfield1": "Again",
            "subfield2": "?"
        }
    },
    {
        "field1": "Hello",
        "field2": "list item 3",
        "field3": null,
        "field4": {
            "subfield1": "World",
            "subfield2": "!"
        }
    },
    {
        "field1": "Hello",
        "field2": "list item 3",
        "field3": null,
        "field4": {
            "subfield1": "Again",
            "subfield2": "?"
        }
    }
]

有没有我可以用来实现这个的库?

除空数组外,您可以对所有值取笛卡尔积。

function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
        const temp = [];
        if (Array.isArray(v) && !v.length) v = null;
        r.forEach(s =>
            (Array.isArray(v) ? v : [v]).forEach(w =>
                (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                    temp.push(Object.assign({}, s, { [k]: x }))
                )
            )
        );
        return temp;
    }, [{}]);
}

const
    data = { field1: "Hello", field2: ["list item 1", "list item 2", "list item 3"], field3: [], field4: [{ subfield1: "World", subfield2: "!" }, { subfield1: "Again", subfield2: "?" }] },
    result = getCartesian(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }