I have a state array of object and i want to concat each URL of an object with all the URLs of the previous objects of it:
navigation:[
{
"type": "LINK",
"uri": "arbress"
},
{
"type": "LINK",
"uri": "arbres-a-grand-developpement"
},
{
"type": "LINK",
"uri": "Acer-xfreemanii"
}
]
An i want the result to be like this :
navigation:[
{
"type": "LINK",
"uri": "arbress"
},
{
"type": "LINK",
"uri": "arbress/arbres-a-grand-developpement"
},
{
"type": "LINK",
"uri": "arbress/arbres-a-grand-developpement/Acer-xfreemanii"
}
]
this is my code but it changed nothing, i always get the initial state:
useEffect(() => {
const newState = navigation.map((obj1) => {
if(obj1.type === 'LINK'){
navigation.map((obj2) => {
if (obj2 === 'LINK'){
return {...obj1, uri: obj2.uri "/" uri}
}
})
}
return obj1;
})
setNavigation(newState)
}
}, [])
CodePudding user response:
Use the index being iterated over in the .map
callback so you can slice the navigation
array from 0 to the index, then join the uri
s of each prior object.
useEffect(() => {
setNavigation(
navigation
.filter(obj => obj.type === 'LINK')
.map((_, i, arr) => ({
type: 'LINK',
uri: arr
.slice(0, i 1) // include this item being iterated over in the result
.map(obj => obj.uri)
.join('/'),
}))
);
}, []);
CodePudding user response:
An alternative to repeated slices would be to pass a string in a closure (here using an IIFE passed to the map()
call) and simply concatenate the next uri part with it on each iteration of the map()
.
useEffect(() => {
setNavigation((navigation) => (
navigation
.filter(({type}) => type === 'LINK')
.map(
((uri) => ({type, uri: tail}) => {
uri = uri === '' ? tail : `${uri}/${tail}`;
return {type, uri};
})('')
)
));
}, []);