JavaScript中如何根据id移动嵌套对象数组中的元素
核心思路
你现有的查找函数仅能获取目标对象本身,无法定位其所属的父级数组与对应索引,因此无法完成「删除原位置元素+插入目标位置」的移动逻辑。我们首先需要优化查找函数,返回更多定位信息,再基于该信息实现移动逻辑。
实现代码
1. 改进版查找函数
// 查找目标对象,返回 {target, parentArr, index},未找到返回null const findNodeInfo = (arr, targetId) => { for (let i = 0; i < arr.length; i++) { const node = arr[i] if (node.id === targetId) { return { target: node, parentArr: arr, index: i } } // 递归查找子数组 if (node.subData?.length) { const res = findNodeInfo(node.subData, targetId) if (res) return res } } return null }
2. 移动函数实现
/** * 移动指定id的节点到目标位置 * @param {Array} root 根数组(也就是你的data数组) * @param {Number} sourceId 要移动的节点id * @param {Number|null} targetParentId 目标父节点id,传null则代表插入到根数组 * @param {Number} targetIndex 插入到目标父数组的索引位置 * @returns {Boolean} 移动成功返回true,失败返回false */ const moveNodeById = (root, sourceId, targetParentId, targetIndex) => { // 查找源节点信息 const sourceInfo = findNodeInfo(root, sourceId) if (!sourceInfo) return false // 找到目标父数组 let targetParentArr if (targetParentId === null) { targetParentArr = root } else { const targetParentInfo = findNodeInfo(root, targetParentId) if (!targetParentInfo) return false targetParentArr = targetParentInfo.target.subData } // 从原位置删除节点 const [movedNode] = sourceInfo.parentArr.splice(sourceInfo.index, 1) // 插入到目标位置 targetParentArr.splice(targetIndex, 0, movedNode) return true }
使用示例
对应你给出的场景,要把id为4的节点移到根数组的最后一位,调用方式如下:
// 你的原始data数组 const data = [ { id: 1, subData: [ { id: 2, subData: [] }, { id: 3, subData: [ { id:4, subData: [] } ] } ] }, { id:5, subData: [] } ] // 移动id=4的节点,到根数组(targetParentId传null)的索引2的位置 moveNodeById(data, 4, null, 2)
执行后输出的data结构和你预期的效果完全一致。
补充说明
- 该实现默认所有节点的id为全局唯一值,符合常规树结构场景需求
- 如果要移动到某个父节点subData的最后一位,
targetIndex可以传父节点.subData.length - 函数返回布尔值可用来判断移动是否成功,比如传入不存在的id时会返回false
内容的提问来源于stack exchange,提问作者qafoori
相关产品推荐
相关产品推荐

