在javascript中重新排序数组

时间:2013-03-25 16:16:42

标签: javascript arrays

有很多关于这个主题的问题/答案。没有符合我的具体情况。希望有人可以提供帮助:

我有一系列索引,例如:

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数组中的索引的items数组中,删除它们,然后最终将它们放回去,彼此相邻在由变量insertindex定义的指定索引处。

我一直在尝试使用splice()将每个索引处的对象复制到临时数组,然后将其从原始数组中删除,最后循环遍历这个新的临时数组并将它们放回原始项目中阵列在新的位置,但似乎击中了心理砖墙,无法使其正常工作。

总而言之,我只想从items数组中获取与indices数组中定义的索引匹配的所有对象,将它们放在一起并将它们重新插入预定义的索引,然后返回到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++;
        }

}

我知道这非常可怕,并且循环三次不应该是必要的。但是我一直在尝试许多不同的方法,一些在一个方向重新排序时工作,一些在另一个方向上工作,而不是在一个方向上。我想我会在以后对其进行优化后再进行优化。

我确信我必须做一些非常愚蠢或完全忽视某事的事情,但对于我的生活,我现在无法解决问题。

2 个答案:

答案 0 :(得分: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;
}));

DEMO: http://jsfiddle.net/T83fB/

为了简化,我使用了Array.map()方法,旧的IE浏览器不支持这种方法。但是,使用MDN中的垫片总是很容易。

答案 1 :(得分:2)

您可以使用.splice()函数向数组添加元素,以及从中删除项目。一般原则是:

  1. 将索引排序为升序数字顺序
  2. 迭代indexes,删除该索引处的元素(调整已删除项目的数量)并将其存储在removedItems数组
  3. removedItems数组添加回所需索引
  4. 执行此操作的代码如下所示:

    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));
    

    看看this jsFiddle demo