我有一个带有对象的数组,可以有多个子对象,这些子对象与父对象具有相同的结构,基本上只是对象嵌套。
我想知道如何通过键删除其中一个对象。例如,我想删除ID为1(嵌套在另一个对象的子级数组中)的对象
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
有可能吗?如果删除带有子对象的对象,那么子对象会移到根目录?
我尝试重做以下函数,该函数从我的数据结构中返回所有ID,因此它获取ID,如果有子代,则获取这些子代内部的ID。但是,如何删除具有该ID的对象?
export function flattenFindAttribute (data, attribute) {
return data.map(item => [item[attribute], ...flattenFindAttribute(item.children)]).flat()
}
答案 0 :(得分:1)
您可以这样:
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
let deletedObj = {}
function deleteAtId(arr, deleteId) {
const rs = []
arr.forEach(({id, children}) => {
if(id !== deleteId) {
if(!children.length) {
rs.push({id, children})
} else {
const tmp = deleteAtId(children, deleteId)
rs.push({id, children: tmp})
}
} else deletedObj = {id, children}
})
return rs
}
const rs = [...deleteAtId(data, 1), {...deletedObj}]
console.log(rs)
答案 1 :(得分:1)
您只需要使用递归function
调用并使用 Array#splice()
method 来删除搜索到的object
。
这应该是您的代码:
function removeId(data, id) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id);
}
});
}
演示:
const data = [{
id: 2,
children: [{
id: 1,
children: []
}]
},
{
id: 3,
children: [],
}
];
function removeId(data, id) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id);
}
});
}
removeId(data, 1);
console.log(data);
如果要将所有已删除的项children
推入其父项children
数组,则只需将第三个参数传递给函数即可跟踪父项object
:
function removeId(data, id, parent) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
if (parent) {
o.children.forEach(c => parent.children.push(c));
}
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id, o);
}
});
}
演示:
var data = [{
id: 2,
children: [{
id: 1,
children: [1, 2]
}]
},
{
id: 3,
children: [],
}
];
function removeId(data, id, parent) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
if (parent) {
o.children.forEach(c=> parent.children.push(c));
}
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id, o);
}
});
}
removeId(data, 1);
console.log(data);
答案 2 :(得分:0)
像这样?递归迭代并在找到具有您ID的对象时进行拼接
function removeObject(data, id){
data.forEach(point =>{
if(point.children.length > 0){
removeObject(point.children, id);
}
const index = data.findIndex(x => x.id == id);
if(index > -1){
data.splice(index ,1);
}
});
return data;
}
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
removeObject(data, 1);
console.log(data)
答案 3 :(得分:0)
以递归方式浏览对象并根据指定的谓词删除该对象:
const data =[...Array(4)].map(()=> [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]);
function deleteObj(parent, predicate) {
if (predicate(parent)) {
return true;
}
if (typeof parent === 'object') {
if (Array.isArray(parent)) {
for (let i = 0; i < parent.length; i++) {
if (deleteObj(parent[i], predicate)) {
parent.splice(i, 1);
i--;
}
}
} else {
Object.keys(parent).forEach(key => deleteObj(parent[key], predicate) && delete parent[key]);
}
}
return false;
}
console.log('from array:', data[0]);
const test1 = data[1];
const test2 = data[2];
const test3 = data[3];
console.log('delete node with id === 1');
deleteObj(test1, node => node.id === 1);
console.log(test1);
console.log('delete node with id === 3');
deleteObj(test2, node => node.id === 3);
console.log(test2);
console.log('delete node with non empty children');
deleteObj(test3, node => node.children && node.children.length > 0);
console.log(test3);
答案 4 :(得分:0)
此递归函数可满足您的需求:
function rotateChildren(array, key) {
if (!array || !array.length) {
return array;
}
return array.filter(child => {
if (child) {
child.children = rotateChildren(child.children, key);
return child.id !== key;
}
return !!child;
});
}
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
];
console.log(rotateChildren(data, 1));
console.log(rotateChildren(data, 2));
console.log(rotateChildren(data, 3));
答案 5 :(得分:0)
您可以使用Array.reduce对子项进行递归来实现。
示例:
const data = [
{ id: 1, children: [{ id: 2, children: [] }] },
{
id: 2,
children: [
{
id: 1,
children: [],
},
],
},
{
id: 3,
children: [],
},
{
id: 4,
children: [
{
id: 2,
children: [
{
id: 2,
children: [
{
id: 1,
children: [],
},
{
id: 2,
children: [],
},
],
},
],
},
],
},
];
function removeBy(data, predicate) {
return data.reduce((result, item) => {
if (!predicate(item.id)) {
const newItem = { ...item };
if (item.children.length > 0) {
newItem.children = removeBy(item.children, predicate);
}
result.push(newItem);
}
return result;
}, []);
}
const predicate = value => value === 1;
const result = removeBy(data, predicate);
console.log(result);