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索引存储在indexes数组中的项目数组中,删除它们,然后最后将它们放回去,所有这些都在变量定义的指定索引处彼此相邻insertindex

我一直在尝试splice()通过将每个索引处的对象复制到临时数组中来使用,然后将它们从原始数组中删除,然后最终循环通过这个新的临时数组并将它们放回新位置的原始项目数组中,但似乎碰到一堵精神砖墙,无法让它正常工作。

总而言之,我只想从 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++;
        }

}

我知道这是非常可怕的,循环三遍应该是不必要的。但是我一直在尝试很多不同的方法,有些在一个方向重新排序时有效,有些在另一个方向上,大部分,根本没有。我想我以后会考虑优化这个功能,一旦我让它准确地工作。

我确定我一定是在做一些非常愚蠢的事情或完全忽略了一些事情,但对于我的一生,我现在无法弄清楚是什么。

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的 shim 总是很容易。

于 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 回答