2017-05-29 116 views
1

鉴于对象数组这样任何级别删除项目:在JS嵌套的对象阵列

var items = [{ 
    id: 1 
}, { 
    id: 2, 
    child: { 
    id: 3 
    } 
}, { 
    id: 4, 
    child: { 
    id: 5, 
    child: { 
     id: 6 
    } 
    } 
}]; 

我需要一种方法在任何水平,以除去一个项目。这段代码做我想要的,但有没有更好的方法?

最初我尝试使用一个递归函数来做,但无法让它工作。

var removed = removeItems(items, 5); 
print(removed); 

function removeItems(items, id) { 
    items.forEach(function(item, index, allItems) { 
    if (item.id === id) { 
     items.splice(index, 1); 
    } 
    if (item.child) { 
     item = testChild(item, item.child, id); 
    } 
    }); 
    return items; 
} 

function testChild(parent, child, id) { 
    if (child.id === id) { 
    delete parent.child 
    return parent; 
    } else { 
    if (child.child) { 
     return testChild(child, child.child, id); 
    } 
    return parent; 
    } 
} 

function print(obj) { 
    document.querySelector('#out').innerHTML += JSON.stringify(obj, null, 2); 
} 

的jsfiddle:https://jsfiddle.net/syvf46uL/12/

回答

1

这里是一个通用的去除,只要你想,应该工作的功能。

var items = [{ 
 
    id: 1 
 
    }, { 
 
    id: 2, 
 
    child: { id: 3 } 
 
    }, { 
 
    id: 4, 
 
    child: { 
 
     id: 5, 
 
     child: { 
 
     id: 6 
 
     } 
 
    } 
 
    } 
 
]; 
 

 
function remove(src, predicate) { 
 
    
 
    // for Array 
 
    if (Array.isArray(src)) { 
 
    for (var i=src.length-1; i>-1; i--) { 
 
     if (predicate(src[i])) { 
 
     src.splice(i, 1); 
 
     } else { 
 
     remove(src[i], predicate); 
 
     } 
 
    } 
 
    } 
 
    
 
    // for Object 
 
    else { 
 
    for (var i in src) { 
 
     if (predicate(src[i])) { 
 
     delete src[i]; 
 
     } else { 
 
     remove(src[i], predicate); 
 
     } 
 
    } 
 
    } 
 
} 
 

 
// remove id == 1 
 
remove(items, function(element) { 
 
    return element.id && element.id == 1; 
 
}); 
 

 
console.log(JSON.stringify(items)); 
 

 
// remove id == 6 
 
remove(items, function(element) { 
 
    return element.id && element.id == 6; 
 
}); 
 

 
console.log(JSON.stringify(items));

一个重要的问题,你的代码,一个很常见的错误,是你试图缩小阵列 - 通过splice方法 - 而迭代前进。这会导致您每次删除元素时都跳过一个元素。

想想这样,你正在迭代0->length;你删除了ith元素;现在你以前的(i + 1)th元素已经成为你的ith元素;但是您仍在迭代0->length,从而导致您跳过新元素ith并转到(i + 1)th元素,该元素是您以前的(i + 2)th元素。这是通过向后迭代来解决的length->0;数组的收缩不会影响迭代器,因为收缩总是从i+1->length开始,但是您从i->0开始迭代。

+0

谢谢EyuelDK –