5

我将 2 个数组传递给一个函数,并希望将特定条目从一个数组移动到另一个数组。moveDatum 函数本身使用 underscorejs 的方法拒绝和过滤。我的问题是,原始数组没有更改,就好像我将数组作为值而不是作为参考传递一样。正确移动了特定条目,但正如我所说,效果只是局部的。我必须改变什么,才能改变原始数组?

调用函数:

this.moveDatum(sourceArr, targetArr, id)

函数本身:

function moveDatum(srcDS, trgDS, id) {
    var ds = _(srcDS).filter(function(el) {
        return el.uid === uid;
    });
    srcDS = _(srcDS).reject(function(el) {
        return el.uid === uid;
    });
    trgDS.push(ds[0]);
    return this;
}

谢谢您的帮助

4

2 回答 2

3

正如评论中提到的,您正在分配srcDS引用由返回的新数组.reject(),因此丢失了对最初从函数外部传入的数组的引用。

您需要直接在原始数组上执行数组操作,可能是这样的:

function moveDatum(srcDS, trgDS, id) {
    var ds;
    for (var i = srcDS.length - 1; i >= 0; i--) {
        if (srcDS[i].uid === id) {
           ds = srcDS[i];
           srcDS.splice(i,1);
        }
    }
    trgDS.push(ds);
    return this;
}

我已经将循环设置为向后移动,这样您就不必担心从数组中删除项目i时循环索引会不同步。.splice()向后循环也意味着ds最终引用该srcDS匹配项中的第一个元素,这是我假设您的意图,因为您的原始代码具有trgDS.push(ds[0]).

如果您碰巧知道该数组将只包含一个匹配项,那么前进或后退当然都没有关系,您可以在break内部添加一个,if因为一旦有匹配项就没有必要继续循环了。

(另外我认为你有一个错字,你正在测试=== uid而不是=== id.)

于 2013-08-24T13:29:20.143 回答
2

在使用修改数组的方法删除之前复制每个匹配项,例如splice.

function moveDatum(srcDS, trgDS, id) { // you pass an `id`, not `uid`?
    var i;
    for (i = 0; i < srcDS.length; ++i) {
        if (srcDS[i].uid === uid) {
            trgDS.push(srcDS[i]);
            srcDS.splice(i, 1); 
            // optionally break here for just the first
            i--; // remember; decrement `i` because we need to re-check the same
                 // index now that the length has changed
        }
    }
    return this;
}
于 2013-08-24T13:32:12.887 回答