首页 > 解决方案 > 如何在 NodeJS 中使用 Map 对具有相同属性值的对象进行分组?

问题描述

3 个 JSON 数组具有 type 的错误详细信息,1如下所示23

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

];

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": {
   "7": {
    "ErrorType": "Error-1A",
    "Error": "wrong ip address for 1A"
   },
      "6": {
    "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": {
      "5": {
    "ErrorType": "Error-3B",
    "Error": "password incorrect for 3B"
   },
   "1": {
    "ErrorType": "Error-3A",
    "Error": "wrong ip address for 3A"
   }
}
}

请注意,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] = result[SERVER_COUNT] ? [...result[SERVER_COUNT], {
    ErrorType,
    Error
}] : [{
    ErrorType,
    Error
}]);
  return result;
}

上面的代码给出了正确的结果。唯一的问题SERVER_COUNT是 不是相反的顺序。如何修改上述函数,以便对于1 2 3我得到的每种类型都SERVER_COUNT首先显示最高值?

Current output:

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

Desired output

{
  "details1": {
   "7": {
    "ErrorType": "Error-1A",
    "Error": "wrong ip address for 1A"
   },
      "6": {
    "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": {
      "5": {
    "ErrorType": "Error-3B",
    "Error": "password incorrect for 3B"
   },
   "1": {
    "ErrorType": "Error-3A",
    "Error": "wrong ip address for 3A"
   }
}
}

我正在尝试Map按以下方式使用,但它给出了 null:

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;
}

标签: javascriptnode.jsarraysdictionarycollections

解决方案


推荐阅读