JS如何对深层嵌套的数组进行增删改查?

问题详情:如题
要求:手撕,当然如果有相关包也可以,我可以去看看源码

const data = [{
    name: '000',
    id: nanoid(),
    child: [
      {
        name: '111',
        id: nanoid(),
        child: []
      }
      ...
    ]
}]

数据类型大概类似上面这种(当然也可以是json数据),每一个元素都有唯一id标识,怎么对它进行增删改查有点头疼。。。

阅读 5.9k
5 个回答

先把这棵树遍历一遍,把树节点拿出来生成一个扁平结构(列表),这个列表里增、改、查都可以解决,毕竟查到了,就可以改,也可以为其添加子节点。不过记得增了子节点之后,这个节点也要放在生成的这个大列表里。

如果想快速查,可以从列表生成一个映射表,用唯一 ID 做键。

如果要删,需要找到要删除的那个节点的父节点,并从其 child 数组中删除去。目前的结构只能通过遍历来查找(当然用列表查还是比较简单),如果如果加一个 parentId 结合映射表,瞬间就找到了。

所以最终可以建立这样一个映射表(示意):

{ id : { node, parentId } }

至于遍历树,参阅:使用递归遍历并转换树形数据(以 TypeScript 为例) - SegmentFault 思否

可以仿造 jsonpath ,在深层嵌套的对象里搜索。

新手上路,请多包涵

将这样的数组,平铺开来转化为一维数组,每项新增一个parentId这个属性用来记录父级。然后,对一维数组进行正删改查。每次结果就是根据一维数组,输出一个树状结果。

新手上路,请多包涵

可以采用类dom的搜索方法 把路径找出来 然后采用eval方式修改值

// JS如何对深层嵌套的数组进行增删改查?

const data = [
    {
        name: "111",
        id: 1,
        child: [
            {
                name: "222",
                id: 2,
                child: [],
            },
            {
                name: "333",
                id: 3,
                child: [
                    {
                        name: "444",
                        id: 4,
                        child: [],
                    },
                    {
                        name: "555",
                        id: 5,
                        child: [],
                    },
                ],
            },
        ],
    },
    {
        name: "666",
        id: 6,
        child: []
    },
    {
        name: "777",
        id: 7,
    }
];

//1, 扁平结构 数据接口 key值可以 遍历
var arr = []

function fixData (data, status, parent, level=0) {
    //console.log("data: ", data);
    data.length>0&&data.map((item) => {
        var obj = { ...item };
        if (status == 1) {
            obj.parentId = parent.id;
            console.log("itemm: ", obj);
        }

        if ((item.child && item.child == 0) || !item.child) {
            arr.push(obj);
        } else {
            obj.child = [];
            obj.isParent = true;
            obj.level = level+1;
            arr.push(obj);
            fixData(item.child, 1, item, obj.level);
            console.log(item,'item');
            
        }
    });

}
fixData(data)

console.log('arr: ', arr);

//2, 更新数据
var forObj = {}
arr.map(v => {
    forObj[v.id]=v
})
console.log("forObj: ", forObj);
console.log("forObj_findKey: ", forObj["1"]);

// 3,还原数据

async function originData(forObj){
    var arr = []
    Object.keys(forObj).forEach((key)=>{
        console.log(key, forObj[key]);
        arr.push(forObj[key]);
    })
    console.log("arr: ", arr);

    var originObj = {}
    var originArr = []
    var originChildArr = []
    await arr.map(item => {
        if (item.isParent || !item.parentId) {
            originArr.push(item);
        } else {
            originChildArr.push(item);
        }
    })

    console.log(originArr)
    console.log(originChildArr)

    await originChildArr.map(item => {
        originArr.map(v => {
            if(item.parentId == v.id){
                v.child.push(item)
            }
        })
    })
    
    console.log(originArr);

    var eleOriginArr = [...originArr];

    await originArr.map((item,i) => {
         eleOriginArr.map((v)=> {
            if(item.id==v.id)return

            if (item.parentId == v.id) {
                v.child.push(item);
                console.log("iiii: ", i)
                eleOriginArr.splice(i,1)
            }

        })
    });
    console.log("eleOriginArr: ", eleOriginArr);
    
}
originData(forObj);

优化后 =》

// JS如何对深层嵌套的数组进行增删改查?

const data = [
    {
        name: "111",
        id: 1,
        child: [
            {
                name: "222",
                id: 2,
                child: [],
            },
            {
                name: "333",
                id: 3,
                child: [
                    {
                        name: "444",
                        id: 4,
                        child: [],
                    },
                    {
                        name: "555",
                        id: 5,
                        child: [],
                    },
                ],
            },
        ],
    },
    {
        name: "666",
        id: 6,
        child: []
    },
    {
        name: "777",
        id: 7,
    }
];

//1, 扁平结构 数据接口 key值可以 遍历
var arr = []

function fixData (data, status, parent, level=0) {
    //console.log("data: ", data);
    data.length>0&&data.map((item) => {
        var obj = { ...item };
        if (status == 1) {
            obj.parentId = parent.id;
            console.log("itemm: ", obj);
        }

        if ((item.child && item.child == 0) || !item.child) {
            arr.push(obj);
        } else {
            obj.child = [];
            obj.isParent = true;
            obj.level = level+1;
            arr.push(obj);
            fixData(item.child, 1, item, obj.level);
            console.log(item,'item');
            
        }
    });

}
fixData(data)

console.log('arr: ', arr);

//2, 更新数据
var forObj = {}
arr.map(v => {
    forObj[v.id]=v
})
console.log("forObj: ", forObj);
console.log("forObj_findKey: ", forObj["1"]);

// 3,还原数据

async function originData(forObj){
    var arr = []
    Object.keys(forObj).forEach((key)=>{
        console.log(key, forObj[key]);
        arr.push(forObj[key]);
    })
    console.log("arr: ", arr);

    var originObj = {}
    var originArr = []
    var originChildArr = []
    await arr.map(item => {
        if (item.isParent || !item.parentId) {
            originArr.push(item);
        } else {
            originChildArr.push(item);
        }
    })

    console.log(originArr)
    console.log(originChildArr)

    await originChildArr.map(item => {
        originArr.map(v => {
            if(item.parentId == v.id){
                v.child.push(item)
            }
        })
    })
    
    console.log(originArr);

    var eleOriginArr = [...originArr];
    await eleOriginArr.map((v,index)=> {
        v.index = index
        originObj[v.id] = v;
    })
    console.log("originObj: ", originObj);
    await originArr.map((item,i) => {
        var targetObj = originObj[item.id+""]
        if(targetObj.parentId){
            var objj = originObj[targetObj.parentId + ""];
            if (objj) {
                originArr.splice(i, 1);
                objj.child.push(targetObj);
            }
        }

    })
    console.log("originArr: ", originArr);



    //await originArr.map((item,i) => {
    //     eleOriginArr.map((v)=> {
    //        if(item.id==v.id)return

    //        if (item.parentId == v.id) {
    //            v.child.push(item);
    //            console.log("iiii: ", i)
    //            eleOriginArr.splice(i,1)
    //        }

    //    })
    //});

    console.log("eleOriginArr: ", eleOriginArr);
    
}
originData(forObj);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏