使用Jquery Splice

时间:2014-07-20 07:29:48

标签: javascript jquery arrays splice

我正在尝试使用Splice方法从数组中删除项目。

arrayFinalChartData =[{"id":"rootDiv","Project":"My Project","parentid":"origin"},{"1":"2","id":"e21c586d-654f-4308-8636-103e19c4d0bb","parentid":"rootDiv"},{"3":"4","id":"deca843f-9a72-46d8-aa85-f5c3c1a1cd02","parentid":"e21c586d-654f-4308-8636-103e19c4d0bb"},{"5":"6","id":"b8d2598a-2384-407a-e2c2-8ae56c3e47a2","parentid":"deca843f-9a72-46d8-aa85-f5c3c1a1cd02"}];
ajax_delete_id = "e21c586d-654f-4308-8636-103e19c4d0bb,deca843f-9a72-46d8-aa85-f5c3c1a1cd02,b8d2598a-2384-407a-e2c2-8ae56c3e47a2";

$.each(arrayFinalChartData, function (idx, obj) {
  var myObj = obj.id;                   
  if (ajax_delete_id.indexOf(myObj) >= 0) {                     
    var vararrayFinalChartDataOne = arrayFinalChartData.splice(idx, 1);
  }
});
console.log(arrayFinalChartData);

请查看:http://jsbin.com/deqix/3/edit

注意:它没有完成"最后一段"循环。这意味着如果我有4个项目,那么它成功执行3个项目。同样适用于6,7 ......项目。

我需要"删除"几件事和"保持平衡"在数组中。

3 个答案:

答案 0 :(得分:0)

您可以使用for循环代替$.each函数:

alert('length before delete ' + arrayFinalChartData.length);
for (var i = arrayFinalChartData.length - 1; i >= 0; i--) {
    id = arrayFinalChartData[i].id;
    if(ajax_delete_id.indexOf(id) > -1){
        arrayFinalChartData.splice(i, 1);
    }
};

alert('length after delete ' + arrayFinalChartData.length);

Demo

答案 1 :(得分:0)

完成编辑:

经过一番研究和控制台记录后,我终于找到了问题所在!它实际上非常简单,但非常偷偷摸摸!

理论解释:

您正在使用变量“idx”调用splice函数,但请记住,splice函数会重新映射/重新索引您的数组!因此,每次拼接数组时,当你仍在$ .each函数内时,它的大小会减一。拼接会搞乱你的数组的jQuery索引,因为jQuery不知道你是从它中删除元素的!

迭代解释:

$。每个函数都会启动,认为你的数组有4个元素,这是真的,但只有一段时间。第一个循环,idx = 0,没有拼接。第二个循环,idx = 1,splice,这意味着你的数组现在剩下3个元素,从0重新索引到2.第三个循环,idx = 2,splice,这意味着你的数组现在剩下两个元素,但是$ .each继续!第四个循环,idx = 3,js崩溃,因为“arrayFinalChartData [3]”未定义,因为每次数组拼接时它都会被移回。

要解决您的问题,您需要使用for循环并从头开始分析数组,而不是从头开始分析,因此每次拼接时,您的索引也会减少。如果您想保持平衡,只需将删除的项目推送到数组中即可。请记住,您正在从最后分析数组,因此推入“removedItems”数组的项目将按相反的顺序排列。就像这样:

var removedItems = new Array();

for (var i = arrayFinalChartData.length - 1; i >= 0; i--) {

    var myObj = arrayFinalChartData[i].id;

    if (ajax_delete_id.indexOf(myObj) >= 0) {

        removedItems.push(arrayFinalChartData.splice(i, 1)[0]);

    }

}

console.log(arrayFinalChartData);
console.log(removedItems);

一个有效的演示(检查页面,观察控制台并点击“运行”):

http://jsfiddle.net/3mL6C/3/

由于another similar thread给了我一个提示,我不会赞美这个答案。

答案 2 :(得分:0)

这里的问题是,当设置$.each时,它会期待一定长度的对象,然后您正在更改。您需要以尊重对象动态长度的方式循环。

var i = 0;  
while (i < arrayFinalChartData.length) {
  var myObj = arrayFinalChartData[i].id;

  if (ajax_delete_id.indexOf(myObj) >= 0) {
     // current item is in the list, so remove it but KEEP THE SAME INDEX
     arrayFinalChartData.splice(i, 1);
  } else {
    // item NOT in list, so MOVE TO NEXT INDEX
    i++
  }

}

console.log(arrayFinalChartData);

Demo