如何在NodeJS中将具有相同属性值的对象分组?

时间:2020-10-22 16:26:22

标签: javascript node.js json collections hashmap

我有3个JSON数组,如下所示。这3个数组的错误详细信息分别为123

const data1 =
[
  {
    "ErrorType": "Error-1A",
    "Error": "wrong ip address for 1A",
    "SERVER_COUNT": 9
  },
  {
    "ErrorType": "Error-1B",
    "Error": "password incorrect for 1B",
    "SERVER_COUNT": 9
  },

];

const data2 = 
[
  {
    "ErrorType": "Error-2A",
    "Error": "wrong data for 2A",
    "SERVER_COUNT": 8
  },
  {
    "ErrorType": "Error-2B",
    "Error": "password incorrect for 2B",
    "SERVER_COUNT": 3
  },

];

const data3 = 
[
  {
    "ErrorType": "Error-3A",
    "Error": "wrong data for 3A",
    "SERVER_COUNT": 1
  },
  {
    "ErrorType": "Error-3B",
    "Error": "password incorrect for 3C",
    "SERVER_COUNT": 5
  },

];

我想结合3个JSON数组data1,data2,data3,最后的JSON对象应如下所示:

{
  "details1": {
   "9": {
    "ErrorType": "Error-1A",
    "Error": "wrong ip address for 1A"
   },
      "9": {
    "ErrorType": "Error-1B",
    "Error": "password incorrect for 1B"
   }
},
  "details2": {
   "8": {
    "ErrorType": "Error-2A",
    "Error": "wrong ip address for 2A"
   },
      "3": {
    "ErrorType": "Error-2B",
    "Error": "password incorrect for 2B"
   }
},
  "details3": {
   "1": {
    "ErrorType": "Error-3A",
    "Error": "wrong ip address for 3A"
   },
      "5": {
    "ErrorType": "Error-3B",
    "Error": "password incorrect for 3B"
   }
}
}

请注意,Error-1AError-1B的计数相同。任何两种错误类型可以具有相同的计数。 我正在使用以下函数循环遍历数组元素,并使用SERVER_COUNT属性作为键将每个元素转换为对象属性。

let finalData = {
  details1: dataToDetails(data1),
  details2: dataToDetails(data2),
  details3: dataToDetails(data3)
};

function dataToDetails (data) {
  let result = {};
  data.forEach(({ErrorType, Error, SERVER_COUNT}) => result[SERVER_COUNT] = {ErrorType, Error});
  return result;
}

但是,它不会同时显示Error-1AError-1B

如何修改上述功能,以便将具有相同SERVER_COUNT值的对象分组?

1 个答案:

答案 0 :(得分:1)

您不是要保存两个对象,而是要一一替换而不是

    result[SERVER_COUNT] = {ErrorType, Error}

您应该做类似的事情

    //There you are get all the objects that are already in result object and add new object to them;
    result[SERVER_COUNT] = result[SERVER_COUNT] ? [...result[SERVER_COUNT], {ErrorType, Error}] : [{ErrorType, Error}]

如果有一些对象具有除Error和ErrorType以外的属性,则最好这样做

    ( { SERVER_COUNT, ...rest } ) => result[ SERVER_COUNT ] = result[ SERVER_COUNT ] ? [ ...result[ SERVER_COUNT ], rest ] : [ rest ] 

使用地图

With Map will be something like


function dataToDetails(data) {
    let result = new Map();
    
    data.sort( ( { SERVER_COUNT: a }, { SERVER_COUNT: b } ) => b - a )

    data.forEach(
        ({ SERVER_COUNT, ...rest }) =>
            result.set(SERVER_COUNT, result.has(SERVER_COUNT)
                ? result.get(SERVER_COUNT).concat([rest])
                : [rest]),
    );
    return result;
}

并使用类似的数组

function dataToDetails(data) {
    let result = [];
    
    data.sort( ( { SERVER_COUNT: a }, { SERVER_COUNT: b } ) => b - a )

    data.forEach(
        ( { SERVER_COUNT, ...rest } ) => {
            const index = result.findIndex( ( [ server_count ] ) => SERVER_COUNT === server_count );
            
            if ( index === -1 ) {
                result.push( [ SERVER_COUNT, [ rest ] ] );
            } else {
                result[ index ][ 1 ].push( rest );
            }
        }
    );
    return result;
}

使用您喜欢的版本。只是响应的格式有所不同,因此请在控制台中进行检查,并且Maps的API不像普通对象那样,因此您可以在Internet上阅读它。

相关问题