javascript - 将 JSON 数据分组到多个键上并保留键

标签 javascript lodash

我有一个如下所示的平面 JSON 文件:

{"dataSet": {"dataTable": [{
    "id": "List1",
    "row": [
        {
            "pagenumber": "7",
            "pageversion": "HE; K12",
            "category": "3D Print - K12;HE",
            "pagetype": "Product",
            "PtrChild": "MakerBot - 10771",
            "Allocation": "0.500",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "7",
            "pageversion": "SL",
            "category": "3D Print - SL",
            "pagetype": "Product",
            "PtrChild": "AUTODESK - 10032",
            "Allocation": "0.500",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "10",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Brand",
            "PtrChild": null,
            "Allocation": "1.000",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "11",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "PtrChild": "EPSON INK JET** - 10082",
            "Allocation": "0.200",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "11",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "PtrChild": "EPSON INK JET** - 10082",
            "Allocation": "0.200",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "11",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "PtrChild": "EPSON INK JET** - 10082",
            "Allocation": "0.500",
            "catext": "Text goes here"
        },
        {
            "pagenumber": "11",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "PtrChild": "LEXMARK** - 10151",
            "Allocation": "0.200",
            "catext": "Text goes here"
        }
    ]
}]}}

我需要按页码、页面版本、PtrChild、分配对数据进行分组,完成后如下所示:

{"pages": [
    {
        "pagenumber": "7",
        "versions": [
            {
                "pageversion": "HE; K12",
                "category": "3D Print - K12;HE",
                "pagetype": "Product",
                "partners": [{
                    "PtrChild": "MakerBot - 10771",
                    "allocations": [{
                        "Allocation": "0.500",
                        "ads": [{"catext": "Text goes here"}]
                    }]
                }]
            },
            {
                "pageversion": "SL",
                "category": "3D Print - SL",
                "pagetype": "Product",
                "partners": [{
                    "PtrChild": "AUTODESK - 10032",
                    "allocations": [{
                        "Allocation": "0.500",
                        "ads": [{"catext": "Text goes here"}]
                    }]
                }]
            }
        ]
    },
    {
        "pagenumber": "10",
        "versions": [{
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Brand",
            "partners": [{
                "PtrChild": null,
                "allocations": [{
                    "Allocation": "1.500",
                    "ads": [{"catext": "Text goes here"}]
                }]
            }]
        }]
    },
    {
        "pagenumber": "11",
        "versions": [{
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "partners": [
                {
                    "PtrChild": "EPSON INK JET** - 10082",
                    "allocations": [
                        {
                            "Allocation": "0.250",
                            "ads": [
                                {"catext": "Text goes here"},
                                {"catext": "Text goes here"}
                            ]
                        },
                        {
                            "Allocation": "0.500",
                            "ads": [{"catext": "Text goes here"}]
                        }
                    ]
                },
                {
                    "PtrChild": "LEXMARK** - 10151",
                    "allocations": [{
                        "Allocation": "0.200",
                        "ads": [{"catext": "Text goes here"}]
                    }]
                }
            ]
        }]
    }
]}

运行这个:

var myGroupedData = nest(myCatalog, ["pagenumber", "pageversion", "PtrChild", "Allocation"]);
// Reorganize JSON data
function nest(collection, keys) {
    if (!keys.length) {
        return collection;
    }
    else {
        return _(collection).groupBy(keys[0]).mapValues(function(values) { 
            return nest(values, keys.slice(1));
        }).value();
    }
}

...获得正确的分组,但消除了每个组的键:

{
    "7": {
        "HE; K12": {"MakerBot - 10771": {"0.500": [{
            "pagenumber": "7",
            "pageversion": "HE; K12",
            "category": "3D Print - K12;HE",
            "pagetype": "Product",
            "PtrChild": "MakerBot - 10771",
            "Allocation": "0.500",
            "catext": "Text goes here"
        }]}},
        "SL": {"AUTODESK - 10032": {"0.500": [{
            "pagenumber": "7",
            "pageversion": "SL",
            "category": "3D Print - SL",
            "pagetype": "Product",
            "PtrChild": "AUTODESK - 10032",
            "Allocation": "0.500",
            "catext": "Text goes here"
        }]}}
    },
    "10": {"Apply to All": {"null": {"1.000": [{
        "pagenumber": "10",
        "pageversion": "Apply to All",
        "category": "Secure Printers",
        "pagetype": "Brand",
        "PtrChild": null,
        "Allocation": "1.000",
        "catext": "Text goes here"
    }]}}},
    "11": {"Apply to All": {
        "EPSON INK JET** - 10082": {
            "0.200": [
                {
                    "pagenumber": "11",
                    "pageversion": "Apply to All",
                    "category": "Secure Printers",
                    "pagetype": "Product",
                    "PtrChild": "EPSON INK JET** - 10082",
                    "Allocation": "0.200",
                    "catext": "Text goes here"
                },
                {
                    "pagenumber": "11",
                    "pageversion": "Apply to All",
                    "category": "Secure Printers",
                    "pagetype": "Product",
                    "PtrChild": "EPSON INK JET** - 10082",
                    "Allocation": "0.200",
                    "catext": "Text goes here"
                }
            ],
            "0.500": [{
                "pagenumber": "11",
                "pageversion": "Apply to All",
                "category": "Secure Printers",
                "pagetype": "Product",
                "PtrChild": "EPSON INK JET** - 10082",
                "Allocation": "0.500",
                "catext": "Text goes here"
            }]
        },
        "LEXMARK** - 10151": {"0.200": [{
            "pagenumber": "11",
            "pageversion": "Apply to All",
            "category": "Secure Printers",
            "pagetype": "Product",
            "PtrChild": "LEXMARK** - 10151",
            "Allocation": "0.200",
            "catext": "Text goes here"
        }]}
    }}
}

如何保留多个键上的键和组?

我被迫使用 ExtendScript,因此无法使用 3.10.1 版本以上的 Lodash。

最佳答案

您可以为每个级别的所需属性使用一个辅助数组,为不同的命名子数组使用最后一个项目,并使用一个方法来提取对象的已使用属性,以获得最终推送的清理对象。

var data = { dataSet: { dataTable: [{ id: "List1", row: [{ pagenumber: "7", pageversion: "HE; K12", category: "3D Print - K12;HE", pagetype: "Product", PtrChild: "MakerBot - 10771", Allocation: "0.500", catext: "Text goes here" }, { pagenumber: "7", pageversion: "SL", category: "3D Print - SL", pagetype: "Product", PtrChild: "AUTODESK - 10032", Allocation: "0.500", catext: "Text goes here" }, { pagenumber: "10", pageversion: "Apply to All", category: "Secure Printers", pagetype: "Brand", PtrChild: null, Allocation: "1.000", catext: "Text goes here" }, { pagenumber: "11", pageversion: "Apply to All", category: "Secure Printers", pagetype: "Product", PtrChild: "EPSON INK JET** - 10082", Allocation: "0.200", catext: "Text goes here" }, { pagenumber: "11", pageversion: "Apply to All", category: "Secure Printers", pagetype: "Product", PtrChild: "EPSON INK JET** - 10082", Allocation: "0.200", catext: "Text goes here" }, { pagenumber: "11", pageversion: "Apply to All", category: "Secure Printers", pagetype: "Product", PtrChild: "EPSON INK JET** - 10082", Allocation: "0.500", catext: "Text goes here" }, { pagenumber: "11", pageversion: "Apply to All", category: "Secure Printers", pagetype: "Product", PtrChild: "LEXMARK** - 10151", Allocation: "0.200", catext: "Text goes here" }] }] } },
    props = [["pagenumber", "versions"], ["pageversion", "category", "pagetype", "partners"], ["PtrChild", "allocations"], ["Allocation", "ads"]],
    result = data.dataSet.dataTable.reduce((r, { row }) => {
        row.forEach(o => props.reduce((a, [...keys]) => {
            var children = keys.pop(),
                temp = a.find(p => p[keys[0]] === o[keys[0]]);
            if (!temp) a.push(temp = Object.assign(...keys.map(k => ({ [k]: o[k] })), { [children]: [] }));
            o = keys.reduce((p, k) => ({ [k]: k, ...p } = p, p), o);
            return temp[children];
        }, r).push(o));
        return r;
    }, []);

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

关于javascript - 将 JSON 数据分组到多个键上并保留键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55873913/

相关文章:

javascript - 在 Angular 7 中嵌入 iframe 是否有安全的方法?

javascript - 将 OpenGL 程序从 C 移植到 WebGL 和 Javascript

javascript - 使用 lodash/underscore .map() 函数的原因是什么?

javascript - 在 underscore.js/lodash.js 中,如何使用 `uniq` 删除重复的元组?

angular - 此模块使用 'export =' 声明,并且只能在使用 'allowSyntheticDefaultImports' 标志时与默认导入一起使用

javascript - 对对象数组进行排序并取 N 个元素

javascript - jquery 中的 Click 事件是永久的吗

javascript - 打印嵌套对象的值

javascript - 使用 javascript 提取并探索 .ZIP 文件夹中的文件修改时间戳

javascript - 使用 lodash 进行数据格式化