5

関数に 2 つの配列を渡し、特定のエントリをある配列から別の配列に移動したいと考えています。moveDatum 関数自体は、underscorejs のメソッド reject と filter を使用します。私の問題は、配列を参照としてではなく値として渡しているかのように、元の配列が変更されないことです。特定のエントリは正しく移動されますが、前述のとおり、効果はローカルのみです。元の配列も変更するには、何を変更する必要がありますか?

関数を呼び出します。

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の最初の要素を参照することも意味します。これは、元のコードに.srcDStrgDS.push(ds[0])

配列に正確に 1 つの一致のみが含まれることがわかっている場合は、もちろん、順方向または逆方向に移動しても問題ありません。また、一致するとループを続行しても意味がないため、break内に a を追加できます。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 に答える