I have array terms
:
[
{
"label": "programming",
"id": 6,
"taxonomy": "category"
},
{
"label": "design",
"id": 4,
"taxonomy": "post_tag"
},
{
"label": "css",
"id": 3,
"taxonomy": "post_tag"
},
{
"label": "other",
"id": 8,
"taxonomy": "category"
}
]
I am trying to create the following newArray
array from array terms
:
[
{
"taxonomy": "category",
"ids": [6, 8]
},
{
"taxonomy": "post_tag",
"ids": [4, 3]
},
]
I have to take the id
from each object in the terms
array and add them to the corresponding taxonomy in the array newArray
.
I am trying the following:
const taxonomyArray = [];
const newArray = [];
// Loop through original term array and get the taxonomies
terms.forEach( el => {
taxonomyArray.push( el['taxonomy'] )
});
// Remove duplicate taxonomy values from array taxonomyArray
const uniqueTaxonomyArray = [ ...new Set(taxonomyArray) ];
// Create the new array
uniqueTaxonomyArray.forEach( el => {
const groupedArray = terms
.filter( ( { taxonomy } ) => taxonomy === el )
.map( ( { value, taxonomy } ) => ( {
taxonomy: el,
ids: value
} ) );
newArray.push( groupedArray );
});
It is giving me:
[
[
{
"taxonomy": "category",
"ids": 6
},
{
"taxonomy": "category",
"ids": 8
}
],
[
{
"taxonomy": "post_tag",
"ids": 4
},
{
"taxonomy": "post_tag",
"ids": 3
}
]
]
Is there a better way to achieve this?
CodePudding user response:
Array.reduce
with Map
const terms = [ { "label": "programming", "id": 6, "taxonomy": "category" }, { "label": "design", "id": 4, "taxonomy": "post_tag" }, { "label": "css", "id": 3, "taxonomy": "post_tag" }, { "label": "other", "id": 8, "taxonomy": "category" }];
const map = terms.reduce((acc, {id, taxonomy}) => {
if (acc.has(taxonomy)) {
acc.get(taxonomy).ids.push(id);
} else {
acc.set(taxonomy, {taxonomy: taxonomy, ids: [id]});
}
return acc;
}, new Map());
const result = [...map.values()];
console.log(result);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
The reducer walks through the array element-by-element, at each step adding the current array value to the result from the previous step (this result is the running sum of all the previous steps) — until there are no more elements to add.
// Arrow function
reduce((previousValue, currentValue) => { ... } )
reduce((previousValue, currentValue, currentIndex) => { ... } )
reduce((previousValue, currentValue, currentIndex, array) => { ... } )
reduce((previousValue, currentValue, currentIndex, array) => { ... }, initialValue)
// Callback function
reduce(callbackFn)
reduce(callbackFn, initialValue)
// Inline callback function
reduce(function(previousValue, currentValue) { ... })
reduce(function(previousValue, currentValue, currentIndex) { ... })
reduce(function(previousValue, currentValue, currentIndex, array) { ... })
reduce(function(previousValue, currentValue, currentIndex, array) { ... }, initialValue)