我有一个如图所示的对象
const arr = [
{
name: 'FolderA',
child: [
{
name: 'FolderB',
child: [
{
name: 'FolderC0',
child: [],
},
{
name: 'FolderC1',
child: [],
},
],
},
],
},
{
name: 'FolderM',
child: [],
},
];
我将路径作为字符串:
var path = "0-0-1".
我必须删除对象:
{
name: 'FolderC1',
child: [],
},
我可以这样做,
arr[0].child[0].splice(1, 1);
但是我想动态地做到这一点。由于路径字符串可以是任何东西,因此我需要上面的“。”动态创建操作符和接头定义以在特定位置进行接头。
答案 0 :(得分:17)
您可以通过保存最后一个索引并返回实际索引的子代来减少索引。稍后拼接上一个索引。
function deepSplice(array, path) {
var indices = path.split('-'),
last = indices.pop();
indices
.reduce((a, i) => a[i].child, array)
.splice(last, 1);
}
const array = [{ name: 'FolderA', child: [{ name: 'FolderB', child: [{ name: 'FolderC0', child: [] }, { name: 'FolderC1', child: [] }] }] }, { name: 'FolderM', child: [] }];
deepSplice(array, "0-0-1");
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:4)
您可以拆分path
并使用这些部分,就像这样:
let path = '0-0-1';
let parts = path.split('-');
// Call your splice using your parts (unsure if your '1' is the index, or deleteCount).
// If parts[2] is the index
arr[parts[0]].child[parts[1]].splice(parts[2], 1);
// If parts[2] is the deleteCount:
arr[parts[0]].child[parts[1]].splice(1, parts[2]);
答案 2 :(得分:2)
您可以编写一个递归函数,该递归函数沿层次结构向下移动直到路径可用。下面是一个非常小的片段。
const arr = [
{
name: 'FolderA',
child: [
{
name: 'FolderB',
child: [
{
name: 'FolderC0',
child: [],
},
{
name: 'FolderC1',
child: [],
},
],
},
],
},
{
name: 'FolderM',
child: [],
},
];
let ar_path = "0-0-1";
function deleteRecursive(arr, path) {
if(Array.isArray(arr) && path.length > 0){
const index = Number(path.shift());
if (path.length > 0)
deleteRecursive(arr[index].child, path)
else
arr.slice(index, 1);
} else {
console.log('invalid');
}
}
deleteRecursive(arr, ar_path.split('-'))
console.log(arr);
答案 3 :(得分:0)
如果路径总是由3个(或更少)索引组成,则可以像下面这样轻松地完成操作:
function deleteByPath(arr, path) {
const index = path.split('-').map((x) => +x);
if ( index.length < 1) {
return null;
} else if ( 1 === index.length ) {
return arr.splice(index[0], 1);
} else if ( 2 === index.length ) {
return arr[index[0]].child.splice(index[1], 1);
} else {
return arr[index[0]].child[index[1]].child.splice(index[2], 1);
}
}
const arr = [
{
name: 'FolderA',
child: [
{
name: 'FolderB',
child: [
{
name: 'FolderC0',
child: [],
},
{
name: 'FolderC1',
child: [],
},
],
},
],
},
{
name: 'FolderM',
child: [],
},
];
console.log(deleteByPath(arr, "0-0-1"));
console.log(deleteByPath(arr, "0-1"));
console.log(deleteByPath(arr, "0"));
如果路径将由少于3个部分组成,则可以调整功能deleteByPath
以根据部分数量处理案例。
如果路径将是任意的并且可以具有任意长度,则可以将deleteByPath
函数调整为递归,如下所示:
function deleteByIndexRecursive(arr, index, current) {
return current+1 < index.length ? deleteByIndexRecursive(arr.child[index[current]], current+1) : arr.child.splice(index[current], 1);
}
function deleteByPath(arr, path) {
const index = path.split('-').map((x) => +x);
if ( 1>index.length) {
return null;
} else if ( 1===index.length) {
return arr.splice(index[0], 1);
} else {
return deleteByIndexRecursive(arr[index[0]], index, 1);
}
}
答案 4 :(得分:0)
//Variable setup:
const arr = [
{
name: 'FolderA',
child: [
{
name: 'FolderB',
child: [
{
name: 'FolderC0',
child: [],
},
{
name: 'FolderC1',
child: [],
},
],
},
],
},
{
name: 'FolderM',
child: [],
},
];
const path = "0-0-1";
//Break the path into pieces to iterate through:
const pathArray = path.split("-");
//Javascript assignments are by reference, so arrayToManage is going to be an internal piece within the original array
let arrayToManage = arr;
//We are going to iterate through the children of the array till we get above where we want to remove
while(pathArray.length > 1){
const key = parseInt(pathArray.shift());
arrayToManage = arrayToManage[key].child;
}
//Get the last position of the last array, where we want to remove the item
const key = parseInt(pathArray.shift());
arrayToManage.splice(key,1);
//And because it's all by reference, changed we made to arrayToManage were actually made on the arr object
console.log("end result:", JSON.stringify(arr));