首页 > 解决方案 > 如何使用节点js中的键对两个数组进行分组

问题描述

我有以下两个要合并的对象。

[
    {
        "response_code": 1,
        "response_message": [{
            "a": 1000,
            "b": 1000001,
            "c": 10000002
        }]
    }]
[
    {
        "response_code": 1,
        "response_message": [{
            "a": 2000,
            "b": 2000001,
            "c": 20000002
        }]
    }
]

我想通过只有一个响应代码值和如下方式合并响应消息值来合并它们,如下所示。

{
    "response_code": 1,
    "response_message": [
    {
        "a": 1000,
        "b": 1000001,
        "c": 10000002
    },
    {
        "a": 2000,
        "b": 2000001,
        "c": 20000002
    }]
}

真的坚持如此复杂的合并,我只想要一次响应代码的值并合并响应消息的值。

在这里,我想从其他数组中删除响应代码值,并将响应消息值与第一个数组合并/分组。

标签: javascriptnode.jsjson

解决方案


我为你准备了一个小功能:

根据您在评论中提出的问题,以及字符串在哪里的测试用例response_message,我编辑了代码片段以包含多个要测试的用例。

const inputs = [
    [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        },

        {
            "response_code": 1,
            "response_message": [{
                "p": 1000,
                "q": 1000001,
                "r": 10000002
            }]
        }
    ],
    [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        },
        {
            "response_code": 1,
            "response_message": 'No data'
        }
    ],
    [{
            "response_code": 1,
            "response_message": 'No data'
        },
        {
            "response_code": 1,
            "response_message": 'No data'
        }
    ]

]

const getGroupedArr = (arr) => {
    const codeMap = arr.reduce((cMap,obj) => {
        let existingMessageArr = cMap.get(obj.response_code);
        let arrayToAdd = Array.isArray(obj.response_message) ? obj.response_message : [];
        if(existingMessageArr){
            existingMessageArr.push(...arrayToAdd);
        } else {
            cMap.set(obj.response_code,arrayToAdd);
        }
        return cMap;
    },new Map());
    const iterator = codeMap[Symbol.iterator]();
    const resultArr = [];
    for (let item of iterator) {
        resultArr.push({
            response_code: item[0],
            response_message: item[1]
        })
    }
    return resultArr;
}

inputs.forEach((inputArr,index) => {
    console.log(`Result for input ${index+1}`,getGroupedArr(inputArr));
})

请注意,我Map在 JS 中使用了大多数人更喜欢对象的位置,因为 JS 中的映射是可迭代的,但是对于一个对象,我不得不做一个额外的Object.keys()步骤,所以这使得它比对象方法稍微更有效,虽然有点冗长.

另请注意,在第三种情况下,当具有特定对象的对象没有response_code任何数据时,结果将是一个空数组而不是字符串。在像 JS 这样的弱类型环境中,保持某种类型一致性始终是一个好习惯(这实际上使得 'No data' 的输入值response_code并不理想),否则您可能需要在任何地方进行类型检查(如在编辑的功能中)在上面的片段中)。

当具有相同的对象response_code存在于两个不同的数组中时(两个输入数组可以简单地合并为一个),可以在评论中提到的约束中使用相同的函数:

const inputArr1 = [{
            "response_code": 1,
            "response_message": [{
                "a": 1000,
                "b": 1000001,
                "c": 10000002
            }]
        }]

const inputArr2 = [{
            "response_code": 1,
            "response_message": [{
                "p": 1000,
                "q": 1000001,
                "r": 10000002
            }]
        }]

const getGroupedArr = (arr) => {
    const codeMap = arr.reduce((cMap,obj) => {
        let existingMessageArr = cMap.get(obj.response_code);
        let arrayToAdd = Array.isArray(obj.response_message) ? obj.response_message : [];
        if(existingMessageArr){
            existingMessageArr.push(...arrayToAdd);
        } else {
            cMap.set(obj.response_code,arrayToAdd);
        }
        return cMap;
    },new Map());
    const iterator = codeMap[Symbol.iterator]();
    const resultArr = [];
    for (let item of iterator) {
        resultArr.push({
            response_code: item[0],
            response_message: item[1]
        })
    }
    return resultArr;
}


console.log(getGroupedArr([...inputArr1,...inputArr2]));


推荐阅读