重新排序数组

时间:2010-03-14 00:31:03

标签: javascript arrays sorting

说,我有一个看起来像这样的数组:

var playlist = [
    {artist:"Herbie Hancock", title:"Thrust"},
    {artist:"Lalo Schifrin", title:"Shifting Gears"},
    {artist:"Faze-O", title:"Riding High"}
];

如何将元素移动到另一个位置?

我想举例,{artist:"Lalo Schifrin", title:"Shifting Gears"}到最后。

我尝试使用拼接,像这样:

var tmp = playlist.splice(2,1);
playlist.splice(2,0,tmp);

但它不起作用。

12 个答案:

答案 0 :(得分:185)

Array.splice的语法是:

yourArray.splice(index, howmany, element1, /*.....,*/ elementX);

其中:

  • index 是您要从
  • 中删除元素的数组中的位置
  • howmany 是您要从索引中删除的元素
  • element1,...,elementX 是您希望从 index 位置插入的元素。

这意味着splice()可用于删除元素,添加元素或替换数组中的元素,具体取决于您传递的参数。

请注意,它会返回已删除元素的数组。

好的和通用的东西是:

Array.prototype.move = function (from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

然后使用:

var ar = [1,2,3,4,5];
ar.move(0,3);
alert(ar) // 2,3,4,1,5

图:

Algorithm diagram

答案 1 :(得分:17)

如果你知道索引,你可以轻松地交换元素,使用这样一个简单的函数:

function swapElement(array, indexA, indexB) {
  var tmp = array[indexA];
  array[indexA] = array[indexB];
  array[indexB] = tmp;
}

swapElement(playlist, 1, 2);
// [{"artist":"Herbie Hancock","title":"Thrust"},
//  {"artist":"Faze-O","title":"Riding High"},
//  {"artist":"Lalo Schifrin","title":"Shifting Gears"}]

数组索引只是数组对象的属性,因此您可以交换其值。

答案 2 :(得分:8)

以下是感兴趣的人的不可变版本:

function immutableMove(arr, from, to) {
  return arr.reduce((prev, current, idx, self) => {
    if (from === to) {
      prev.push(current);
    }
    if (idx === from) {
      return prev;
    }
    if (from < to) {
      prev.push(current);
    }
    if (idx === to) {
      prev.push(self[from]);
    }
    if (from > to) {
      prev.push(current);
    }
    return prev;
  }, []);
}

答案 3 :(得分:5)

删除元素时,将2更改为1作为splice调用中的第一个参数:

var tmp = playlist.splice(1, 1);
playlist.splice(2, 0, tmp[0]);

答案 4 :(得分:3)

如果你不知道目前的记录在哪里,你总是可以使用sort方法:

playlist.sort(function (a, b) {
    return a.artist == "Lalo Schifrin" 
               ? 1    // Move it down the list
               : 0;   // Keep it the same
});

答案 5 :(得分:1)

试试这个:

playlist = playlist.concat(playlist.splice(1, 1));

答案 6 :(得分:1)

如果您只想将一个项目从任意位置移动到数组的末尾,这应该有效:

function toEnd(list, position) {
    list.push(list.splice(position, 1));
    return list;
}

如果您想将多个项目从任意位置移动到最后,您可以执行以下操作:

function toEnd(list, from, count) {
    list.push.apply(list, list.splice(from, count));
    return list;
}

如果要将多个项目从某个任意位置移动到某个任意位置,请尝试:

function move(list, from, count, to) {
    var args = [from > to ? to : to - count, 0];
    args.push.apply(args, list.splice(from, count));
    list.splice.apply(list, args);

    return list;
}

答案 7 :(得分:1)

编辑:请先查看Andy's answer,因为他的回答排在第一位,这仅仅是他的扩展

我知道这是一个古老的问题,但是我认为值得加入Array.prototype.sort()

以下是MDN along with the link

中的一个示例
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

// [1, 2, 3, 4, 5]

幸运的是,它不仅适用于数字:

  

arr.sort([compareFunction])

     

compareFunction

     

指定一个定义排序顺序的函数。如果省略,则根据每个字符的Unicode代码点值和每个元素的字符串转换对数组进行排序。

我注意到您正在按名字订购它们:

let playlist = [
    {artist:"Herbie Hancock", title:"Thrust"},
    {artist:"Lalo Schifrin", title:"Shifting Gears"},
    {artist:"Faze-O", title:"Riding High"}
];

// sort by name
playlist.sort((a, b) => {
  if(a.artist < b.artist) { return -1; }
  if(a.artist > b.artist) { return  1; }

  // else names must be equal
  return 0;
});

请注意,如果您想按姓氏顺序订购它们,则必须要么拥有first_namelast_name的钥匙,要么要做一些正则表达式魔术,而我做不到XD

希望有帮助:)

答案 8 :(得分:1)

不可变版本,无副作用(不改变原始数组):

const testArr = [1, 2, 3, 4, 5];

function move(from, to, arr) {
    const newArr = [...arr];

    const item = newArr.splice(from, 1)[0];
    newArr.splice(to, 0, item);

    return newArr;
}

console.log(move(3, 1, testArr));

// [1, 4, 2, 3, 5]

代码笔:https://codepen.io/mliq/pen/KKNyJZr

答案 9 :(得分:0)

作为一种简单的可变解决方案,您可以连续两次调用拼接:

playlist.splice(playlist.length - 1, 1, ...playlist.splice(INDEX_TO_MOVE, 1))

另一方面,一个简单的不可变解决方案可以使用slice,因为此方法从原始数组中返回一个节的副本而不更改它:

const copy = [...playlist.slice(0, INDEX_TO_MOVE - 1), ...playlist.slice(INDEX_TO_MOVE), ...playlist.slice(INDEX_TO_MOVE - 1, INDEX_TO_MOVE)]

答案 10 :(得分:0)

使用 ES6 ,您可以执行以下操作:

const swapPositions = (array, a ,b) => {
  [array[a], array[b]] = [array[b], array[a]]
}

let array = [1,2,3,4,5];
swapPositions(array,0,1);

/// => [2, 1, 3, 4, 5]

答案 11 :(得分:-1)

以这种方式重新安排工作

 var tmpOrder = playlist[oldIndex];
    playlist.splice(oldIndex, 1);
    playlist.splice(newIndex, 0, tmpOrder);

我希望这会起作用