javascript 通过属性相同的数组进行Map和分组

atmip9wb  于 2023-02-07  发布在  Java
关注(0)|答案(2)|浏览(123)

我有一个数组返回如下:

errors = [
    {
        "row": 1,
        "key": "volume",
        "errorType": "Data type",
        "expectedType": "number",
        "receivedType": "string"
    },
    {
        "row": 1,
        "key": "units",
        "errorType": "Required data",
        "expectedType": "string"
    },
    {
        "row": 3,
        "key": "year",
        "errorType": "Incorrect data type",
        "expectedType": "number",
        "receivedType": "string"
    },
    {
        "row": 3,
        "key": "make",
        "errorType": "Required data",
        "expectedType": "string"
    }
]

我想返回一个对象数组,如下所示:

const errorGrouped = [
  {
  row:1,
  data:[
    {
      "key":"volume",
      "errorType": "Data type",
      "expectedType": "number",
      "receivedType": "string"
    },
    {
      "key": "units",
      "errorType": "Required data",
      "expectedType": "string"
    }
  ]
  },
  {
  row:3,
  data:[
    {
      "key": "year",
      "errorType": "Incorrect data type",
      "expectedType": "number",
      "receivedType": "string"
    },
    {
      "key": "make",
      "errorType": "Required data",
      "expectedType": "string"
    }
  ]
  }
]

我尝试过Map每个对象,将其解构为所需的[{row:..,data:[...]}]形式,但我找不到一种明显而清晰的分组方式--这向我暗示了一种更好的方法。
但是,是的,感谢任何人可以提供的帮助。谢谢

fae0ux8s

fae0ux8s1#

您可以通过使用hash(JS对象)在单个循环中实现这一点

  • 哈希将行索引存储在数组中,这样您就不必再次查找
  • 一旦你有了索引,你只需要访问数组的位置来推送数据
const errors = [
    {
        "row": 1,
        "key": "volume",
        "errorType": "Data type",
        "expectedType": "number",
        "receivedType": "string"
    },
    {
        "row": 1,
        "key": "units",
        "errorType": "Required data",
        "expectedType": "string"
    },
    {
        "row": 3,
        "key": "year",
        "errorType": "Incorrect data type",
        "expectedType": "number",
        "receivedType": "string"
    },
    {
        "row": 3,
        "key": "make",
        "errorType": "Required data",
        "expectedType": "string"
    }
];

const rowMapIndex = {};
const output = [];

for (let rowObj of errors) {
    const { row: rowID, ...restObj } = rowObj;

    let addAt = output.length;
    if (rowID in rowMapIndex)  {
        addAt = rowMapIndex[rowID];
    } else {
        rowMapIndex[rowID] = output.length;
        output.push({ row: rowID, data: [] });
    }
    output[addAt].data.push(restObj)
};

console.log(output);
axr492tv

axr492tv2#

可以在JS中使用reduce方法。

const errorGrouped = errors.reduce((accumulatorList, error) => {
    const group = accumulatorList.find(g => g.row === error.row);    
    if (group) {
        // if the row is already there
        group.data.push(error);
    } else {
        // if this is a new row
        accumulatorList.push({ row: error.row, data: [error] });
    }
    // remove row attribute from the error object
    delete error.row;

    
    return accumulatorList;
}, []);

console.log(errorGrouped);

相关问题