简体   繁体   English

如何在Javascript中将对象数组转换为嵌套对象数组?

[英]How to convert array of object into nested array of object in Javascript?

I am having an array of objects like this我有一个这样的对象数组

[
    {
        name: "dhanush",
        goals: ["goal 1","goal 2"]
    },
    {
        name: "kumar",
        goals: ["goal 3", "goal 4"]
    },
    {
        name: "test",
        goals: ["goal 5"]
    }
]

Is that possible to convert the above array of object into the below structure like this是否可以像这样将上面的对象数组转换为下面的结构

[
  {
    "name": "dhanush",
    "goals": "---",
    "subRows": [
      {
        "name": "",
        "goals": "goal 1"
      },
      {
        "name": "",
        "goals": "goal 2"
      }
    ]
  },
  {
    "name": "kumar",
    "goals": "---",
    "subRows": [
      {
        "name": "",
        "goals": "goal 3"
      },
      {
        "name": "",
        "goals": "goal 4"
      }
    ]
  },
  {
    "name": "Test",
    "goals": "goal 5"
  }
]

In the first data, you can see the user has multiple goals (which means the array length is more than 1), If the goal length is more than one, need to create another key and move the goal data into the above structure like this.在第一个数据中,你可以看到用户有多个目标(这意味着数组长度大于1),如果目标长度大于一个,需要创建另一个键并将目标数据移动到上面这样的结构中.

Why I am doing this because I got an ask to create a table that needs to support expandable rows.为什么我这样做是因为有人要求我创建一个需要支持可扩展行的表。 I used @tanstack/react-table for this row expansion.我使用@tanstack/react-table进行此行扩展。 Here you can find the working demo link - https://codesandbox.io/s/tanstack-table-expansion-1t77ks?file=/src/App.js在这里您可以找到工作演示链接 - https://codesandbox.io/s/tanstack-table-expansion-1t77ks?file=/src/App.js

In the demo, you can see the row can expand.在演示中,您可以看到行可以展开。 For the expansion that table requires the data format like this.对于表的扩展需要这样的数据格式。

I tried to do something like this,我试图做这样的事情,

var data = [
    {
        name: "dhanush",
        goals: ["goal 1","goal 2"]
    },
    {
        name: "kumar",
        goals: ["goal 3", "goal 4"]
    },
    {
        name: "test",
        goals: ["goal 5"]
    }
]


let result = data.map((val,i) => {
  return {
    name: val.name,
    ...(val.goals.length === 1 && {goals: val.goals[0]}),
    [val.goals.length > 1 && 'subRows']: data.map((t,j) => {
      return{
       name: "",
       goals: val.goals[j]
      }
       
    }),
  }
})

But the output I am getting like this instead of the actual structure但是我得到的输出是这样的,而不是实际的结构

[
  {
    "name": "dhanush",
    "subRows": [
      {
        "name": "",
        "goals": "goal 1"
      },
      {
        "name": "",
        "goals": "goal 2"
      },
      {
        "name": ""
      }
    ]
  },
  {
    "name": "kumar",
    "subRows": [
      {
        "name": "",
        "goals": "goal 3"
      },
      {
        "name": "",
        "goals": "goal 4"
      },
      {
        "name": ""
      }
    ]
  },
  {
    "name": "test",
    "goals": "goal 5",
    "false": [
      {
        "name": "",
        "goals": "goal 5"
      },
      {
        "name": ""
      },
      {
        "name": ""
      }
    ]
  }
]

Could you please help to achieve this?你能帮助实现这一目标吗?

Don't try to do this all in a single object literal, it's a confusing way to create properties conditionally.不要试图在单个对象文字中完成所有这些操作,这是有条件地创建属性的一种令人困惑的方式。 Just write normal conditional statements.只需编写正常的条件语句。

 var data = [{ name: "dhanush", goals: ["goal 1", "goal 2"] }, { name: "kumar", goals: ["goal 3", "goal 4"] }, { name: "test", goals: ["goal 5"] } ] var result = data.map(({ name, goals }) => { let item = { name }; if (goals.length == 1) { item.goals = goals[0]; } else { item.goals = "---"; item.subRows = goals.map(g => ({ name: "", goals: g })); } return item; }); console.log(result);

This here这里

[val.goals.length > 1 && 'subRows']: data.map((tm j) => {

evaluates to false if there's 1 goal or less, and results in the string property false .如果有 1 个或更少的目标,则评估为false ,并导致字符串属性false Then you're mapping the whole data again inside that for some reason.然后,出于某种原因,您再次将整个data映射到其中。 Only map over the goals of the current element you're iterating over, the val.goals .仅映射您正在迭代的当前元素的目标,即val.goals

Because the different possible resulting objects are pretty differently strucured, I think this would be easier to manage if they were entirely separate - return { name, goals: goals[0] } if there's only one goal, and return a completely different object mapping over the goals otherwise.因为不同的可能结果对象的结构非常不同,所以我认为如果它们完全分开,这将更容易管理 - 如果只有一个目标,则返回{ name, goals: goals[0] } ,并返回完全不同的对象映射否则的goals

 var data=[{name:"dhanush",goals:["goal 1","goal 2"]},{name:"kumar",goals:["goal 3","goal 4"]},{name:"test",goals:["goal 5"]}]; const result = data.map(({ name, goals }) => { return goals.length === 1 ? { name, goals: goals[0] } : { name, goals: '---', subRows: goals.map( goal => ({ name: '', goal }) ) }; }); console.log(result);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM