4

このトピックを扱う多くの質問/回答があります。私の特定のケースに一致するものはありません。うまくいけば、誰かが助けることができます:

次のようなインデックスの配列があります。

var indexes = [24, 48, 32, 7, 11];

そして、これに似たオブジェクトの配列:

var items = [{
              name : "whatever",
              selected : false,
              loading : true,
              progress : 55,
              complete : false
},
{
              name : "whatever 2",
              selected : false,
              loading : false,
              progress : 100,
              complete : true
}];

配列内の各整数はindexes、items配列内のオブジェクトの実際のインデックスに対応します。

最後に、items配列内の新しい挿入位置を定義する変数があります。

 var insertindex = ??

私がやりたいのobjectsは、インデックスが配列に格納されているitems配列のすべてを取得しindexes、それらを削除してから、最後に、変数で定義された指定されたインデックスにすべて並べて配置することですinsertindex

splice()各インデックスのオブジェクトを一時配列にコピーし、元の配列から削除し、最後にこの新しい一時配列をループして、新しい位置で元のアイテム配列に戻すことで使用しようとしていますが、精神的なレンガの壁にぶつかって、それを正しく機能させることができません。

要約すると、indexes配列で定義されたインデックスに一致するitems配列からすべてのオブジェクトを取得し、それらをまとめて、事前定義されたインデックスに再挿入し、items配列に戻します。

概念的な視覚化を支援するため。アプリをjavascriptファイルマネージャーと考えると、隣接している必要のない複数のファイル選択の並べ替えが可能になります。現在のindexes選択を定義するitems配列とファイルのリストを定義する配列。そして最後に、rearoderindexは、選択したすべてのファイルが移動する新しい挿入位置を定義します。

編集:ここで正しく提案されたように、私が今遊んでいるコードは次のとおりです:

function reorder(items, indexes, insertindex){

        var offset = 0;
        var itemscopy = items.slice(0); //make shallow copy of original array
        var temparray = new Array(); // create temporary array to hold pulled out objects

        //loop through selected indexes and copy each into temp array
        for(var i=0, len=indexes.length; i<len; i++){ 
            array[i] = itemscopy[self.cache.selecteditems[i]];
        }


        //remove all selected items from items array
        for(var i=0, len=indexes.length; i<len; i++){
            items.splice(indexes[i], 1);
        }

        //finally loop through new temp array and insert the items back into the items array at the specified index, increasing the index each iteration using the offset variable.
        for(var i=0, len=temparray.length; i<len; i++){
            items.splice((insertindex+offset), 0, array[i]);
            offset++;
        }

}

これはかなりひどいことであり、3回ループする必要はないはずです。しかし、私はさまざまな方法を試してきました。ある方向に並べ替えるときに機能する方法もあれば、ほとんどの場合、まったく機能しない方法もあります。正確に機能するようになったら、後で関数を最適化することを検討すると思いました。

私は何かを非常に愚かであるか完全に見落としているに違いないと確信していますが、私の人生のために、私は今何を理解することができません。

4

2 に答える 2

5

配列の順序を気にしない場合はindexes、別の短い解決策をお勧めします。

items.splice.apply(items, [insertIndex, 0].concat(indexes.sort(function(a, b) {
    return a - b;
})).map(function(i, p) {
    return p > 1 ? items.splice(i - p + 2, 1).pop() : i;
}));

デモ:http: //jsfiddle.net/T83fB/

簡単に言うとArray.map()、古いIEブラウザではサポートされていない方法を使用しました。ただし、 MDNのシムはいつでも簡単に使用できます。

于 2013-03-26T11:12:44.917 に答える
2

この関数を使用し.splice()て、配列に要素を追加したり、配列から項目を削除したりできます。一般的な原則は次のとおりです。

  1. インデックスを昇順で並べ替える
  2. 繰り返しindexes、そのインデックスの要素を削除し(削除されたアイテムの数を調整)、removedItems配列に格納します
  3. removedItems必要なインデックスにアレイを追加し直します

これを行うためのコードは次のようになります。

var removedItems = [];
// sort indexes
indexes.sort(function(a, b) {
    if(a < b) return -1;
    else if(b < a) return 1;
    return 0;
});
for(var i = 0; i < indexes.length; i++) {
    var index = indexes[i];
    removedItems.push(items.splice(index - removedItems.length, 1));
}
var insertIndex = 1;
items.splice.apply(items, [insertIndex, 0].concat(removedItems));

このjsFiddleデモをご覧ください。

于 2013-03-25T16:30:35.770 に答える