I have an array of objects as follows
const array = [
{id:1,parentIds:[]}
{id:2,parentIds:[1,3]}
{id:3,parentIds:[1,2,4]}
]
How can I make it possible to remove an object's parentIds value if it doesn't exist in the array? to look something like this
const array = [
{id:1,parentIds:[]}
{id:2,parentIds:[1,3]}
{id:3,parentIds:[1,2]}
]
CodePudding user response:
You can try this solution:
const array = [{
id: 1,
parentIds: []
}, {
id: 2,
parentIds: [1, 3]
}, {
id: 3,
parentIds: [1, 2, 4]
}];
const idsArr = array.map(el => el.id);
array.forEach(el => {
el.parentIds = el.parentIds.filter(el => idsArr.includes(el));
})
console.log(array);
CodePudding user response:
It's better to avoid mutating the original array parentIds
, use immutation to create new array:
const array = [
{id:1,parentIds:[]},
{id:2,parentIds:[1,3]},
{id:3,parentIds:[1,2,4]}
]
const ids = array.map(({id}) => id)
const newArray = array.map(({parentIds,...arrayItemRest}) => {
const newparentIds = parentIds.filter(id => ids.includes(id))
return {
...arrayItemRest,
parentIds: newparentIds
}
})
CodePudding user response:
const array = [
{id:1,parentIds:[]},
{id:2,parentIds:[1,3]},
{id:3,parentIds:[1,2,4]}
]
// Let's create an array only containing the ids
var ids = array.map(o => o.id)
// Loop array
array.forEach((object) => {
// Loop all parent ids
object.parentIds.forEach((id, index) => {
// Check if we find the id in our list
if (ids.indexOf(id) === -1) {
// Delete item from array if not found
object.parentIds.splice(index, 1)
}
})
})
// The result
console.log(array)
CodePudding user response:
You can map
(documentation here) your parent Ids and then filter using the includes
method (documentation here)
const array = [{
id: 1,
parentIds: []
},
{
id: 2,
parentIds: [1, 3]
},
{
id: 3,
parentIds: [1, 2, 4]
}
]
const parents = array.map(x => x.id)
array.forEach(item => {
item.parentIds = item.parentIds.filter(x => parents.includes(x))
})
console.log(array)
CodePudding user response:
Loop through inner parentIds array and remove members that are not any of the outer ids.
const array = [
{ id: 1, parentIds: [] },
{ id: 2, parentIds: [1, 3] },
{ id: 3, parentIds: [1, 2, 4] }
];
array.forEach(
(o) =>
(o.parentIds = o.parentIds.filter((pI) =>
array.map((o) => o.id).includes(pI)
))
);
console.log(array);
CodePudding user response:
Get a list of keys/ids using map
, and then map
over the array of objects to filter
out the parentIds that are missing, returning a new array of updated objects.
const data=[{id:1,parentIds:[]},{id:2,parentIds:[1,3]},{id:3,parentIds:[1,2,4]}];
function removeIds(data) {
// Get the ids from all the array objects
const keys = data.map(obj => obj.id);
// `map` over the array and return a new
// array of updated objects
return data.map(obj => {
const newIds = obj.parentIds.filter(id => {
return keys.includes(id);
});
return { ...obj, parentIds: newIds };
});
}
console.log(removeIds(data));
CodePudding user response:
Well basic way would be to go trough array every time there is a change, and update parentIds list.
To do that:
const dummyArray = [
{id:1,parentIds:[]},
{id:2,parentIds:[1,3]},
{id:3,parentIds:[1,2,4]}
];
/* You can do this with regular array, this only ensures that ids are unique */
const idsSet = new Set();
dummyArray.forEach(it => idsSet.add(it.id));
dummyArray.forEach(it => {
/* If you are using array, you would need to loop trough for each id and check if existing */
const newParentIds = it.parentIds.filter(id => idsSet.has(id));
it.parentIds = newParentIds;
console.log(it.parentIds);
});
There would be a better solution for this for sure, so please try to take this as an example for logic which can be used.
CodePudding user response:
From the above comments ...
As long as one does not know, what actually describes a reliable parent-child description one can not solve the task. Thus if one assumes the above being such a stable description one has to work oneself from the first to the last item, collecting with each step all the already processed
id
values and then, within each currently processedparentIds
array, one has to remove anyid
value which is not part of the current id-collection.
A reduce
based approach can achieves both, implementing the performant lookup and not altering/mutating the original data structure ...
const array = [
{ id:1, parentIds: [] },
{ id:2, parentIds: [1,3] },
{ id:3, parentIds: [1,2,4] },
];
const sanitizedArray = array
.reduce(({ lookup, result }, { id, parentIds, ...rest }) => {
lookup[id] = true;
result.push({
id,
parentIds: parentIds.filter(parentId => !!lookup[parentId]),
...rest,
});
return { lookup, result };
}, { lookup: {}, result: [] }).result;
console.log({
array,
sanitizedArray,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
CodePudding user response:
const array = [
{ id: 1, parentIds: [] },
{ id: 2, parentIds: [1, 3] },
{ id: 3, parentIds: [1, 2, 4] },
];
const removeParentIds = (array) => {
return array.map((item) => {
const { parentIds } = item;
return {
...item,
parentIds: parentIds.filter((parentId) => array.some((item) => item.id === parentId)),
};
});
}
console.log(removeParentIds(array));
CodePudding user response:
You can add childIds in each object, so when you remove one object you can go through each of child's and remove from it's parents as-well.
const array = [
{id:1,parentIds:[],childIds:[2,3]},
{id:2,parentIds:[1,3],childIds:[3]},
{id:3,parentIds:[1,2],childIds:[2]}
]
function idChecker(id){
for(let i=0; i<array.length;i ) if(array[i].id === id) return i;
return undefined
}
function removeObject(id){
let key = idChecker(id)
if(key === undefined) return false
let children = array[key].childIds
children.map(val => {
let keyOfVal = idChecker(val)
array[keyOfVal].parentIds.splice(array[keyOfVal].parentIds.indexOf(id), 1)
})
array.splice(idChecker(id), 1)
return true
}