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.
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. Here you can find the working demo link - 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?
CodePudding user response:
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);
CodePudding user response:
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
. Then you're mapping the whole data
again inside that for some reason. Only map over the goals of the current element you're iterating over, the 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.
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);