I have an object as per below:
{
items: [
{
id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
name: 'Car',
items: [],
},
{
id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
name: 'Toolbox',
items: [
{
id: '1764e295-4ee7-4455-80b4-ea011e111785',
name: 'Spanner',
items: [],
},
{
id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
name: 'Hammer',
items: [],
},
],
},
{
id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
name: 'Shed',
items: [
{
id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
name: 'Axe',
items: [],
},
],
},
],
};
I am trying to figure out two things:
- Get an array of objects, where the key is 'name' (e.g. below)
var array = [{name: 'Car'}, {name: 'Toolbox'}, {name: 'Spanner'}, {name: 'Hammer'}, {name: 'Shed'}, {name: 'Axe'}]
- Get an array of objects, where the key is 'name' but has no items below it (essentially childless) (e.g. below)
var array = [{name: 'Car'}, {name: 'Spanner'}, {name: 'Hammer'}, {name: 'Axe'}]
I attempted putting something together that iterates to a list and pushes to an array but after the 3rd nested loop, I knew I was doing something wrong.
I've also explored Object.entries
but it only gets the top layer.
CodePudding user response:
var array = [];
var name;
items.forEach(item=>{
name = item.name;
array.push(name);
});
Output: var array = [name: 'Car', name: 'Toolbox', name: 'Spanner', name: 'Hammer', name: 'Shed', name: 'Axe']
Note: if you are using older version of js, instead of forEach loop, you can use old traditional for loop.
CodePudding user response:
You can use recursion to check all items and child items
const data = {
items: [
{
id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
name: 'Car',
items: [],
},
{
id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
name: 'Toolbox',
items: [
{
id: '1764e295-4ee7-4455-80b4-ea011e111785',
name: 'Spanner',
items: [],
},
{
id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
name: 'Hammer',
items: [],
},
],
},
{
id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
name: 'Shed',
items: [
{
id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
name: 'Axe',
items: [],
},
],
},
],
};
const getNames = (items, result = []) => {
for(const item of items) {
if(!item.items || !item.items.length) {
// no sub-items, just push name to the result
result.push({ name: item.name })
} else {
//loop through all child items to find child names
result = getNames(item.items, result)
}
}
return result
}
const finalResult = getNames(data.items)
console.log(finalResult)
Another version with concat
(no result
param) in recursion
const data = {
items: [
{
id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
name: 'Car',
items: [],
},
{
id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
name: 'Toolbox',
items: [
{
id: '1764e295-4ee7-4455-80b4-ea011e111785',
name: 'Spanner',
items: [],
},
{
id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
name: 'Hammer',
items: [],
},
],
},
{
id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
name: 'Shed',
items: [
{
id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
name: 'Axe',
items: [],
},
],
},
],
};
const getNames = (items) => {
let result = []
for(const item of items) {
if(!item.items || !item.items.length) {
result.push({ name: item.name })
} else {
result = result.concat(getNames(item.items))
}
}
return result
}
const finalResult = getNames(data.items)
console.log(finalResult)
CodePudding user response:
You can get both the results just by passing an extra argument to the function according to your need:
- Get an array of objects, where Key is 'name' but has no items below it (essentially childless):
prepareData(data?.items, true)
- Get an array of objects, where Key is 'name':
prepareData(data?.items)
const data = {
items: [{
id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
name: 'Car',
items: [],
},
{
id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
name: 'Toolbox',
items: [{
id: '1764e295-4ee7-4455-80b4-ea011e111785',
name: 'Spanner',
items: [],
},
{
id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
name: 'Hammer',
items: [],
},
],
},
{
id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
name: 'Shed',
items: [{
id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
name: 'Axe',
items: [],
}, ],
},
],
};
const result = []
function prepareData(items, isChildless = false) {
items?.forEach((list) => {
if (!list ?.items?.length) {
result.push({
name: list?.name
});
} else {
!isChildless && result.push({
name: list?.name
});
prepareData(list?.items, isChildless);
}
})
}
prepareData(data?.items, true) // if you want to get array of object of all childless items
// prepareData(data?.items) // if you want to get array of object of items which includes items with all the children
console.log(result)