【问题标题】:How to group objects with the same property value in NodeJS?如何在 NodeJS 中对具有相同属性值的对象进行分组?
【发布时间】:2021-02-05 17:18:27
【问题描述】:

我有 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值相同的对象分组?

【问题讨论】:

    标签: javascript node.js json collections hashmap


    【解决方案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;
    }
    

    使用你喜欢的版本。只是响应的格式不同,所以在控制台中检查它,而且地图有 API 不像普通对象,所以你可以在互联网上阅读它。

    【讨论】:

    • 谢谢。如何按时间倒序获得输出?例如对于123 类型,它应该首先显示错误,最大值为SERVER_COUNT
    • 那么最好使用数组或映射而不是对象,因为在对象属性中总是排序
    • 带地图会是这样的
    • 您能否使用 Map 数组修改您的答案?非常感谢!!
    • 我正在使用您在上面给出的 Map 函数,但它返回 null。你能检查一下吗?
    猜你喜欢
    • 2018-10-24
    • 1970-01-01
    • 2013-10-14
    • 2012-06-27
    • 2018-01-21
    • 2023-04-02
    • 2020-04-24
    • 1970-01-01
    相关资源
    最近更新 更多