developer tip

배열 재정렬

copycodes 2020. 9. 15. 07:56
반응형

배열 재정렬


다음과 같은 배열이 있습니다.

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

하지만 작동하지 않습니다.


구문 Array.splice은 다음과 같습니다.

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

어디:

  • index 는 요소 제거를 시작하려는 배열의 위치입니다.
  • howmany인덱스 에서 제거하려는 요소의 수입니다.
  • element1, ..., elementXindex 위치에서 삽입하려는 요소 입니다.

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

도표:

알고리즘 다이어그램


If you know the indexes you could easily swap the elements, with a simple function like this:

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"}]

Array indexes are just properties of the array object, so you can swap its values.


Here is an immutable version for those who are interested:

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;
  }, []);
}

Change 2 to 1 as the first parameter in the splice call when removing the element:

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

You could always use the sort method, if you don't know where the record is at present:

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

With ES6 you can do something like this:

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]

Try this:

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

If you only ever want to move one item from an arbitrary position to the end of the array, this should work:

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

If you want to move multiple items from some arbitrary position to the end, you can do:

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

If you want to move multiple items from some arbitrary position to some arbitrary position, try:

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

EDIT: Please check out Andy's answer as his answer came first and this is solely an extension of his

I know this is an old question, but I think it's worth it to include Array.prototype.sort().

Here's an example from 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]

Luckily it doesn't only work with numbers:

arr.sort([compareFunction])

compareFunction

Specifies a function that defines the sort order. If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.

I noticed that you're ordering them by first name:

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

note that if you wanted to order them by last name you would have to either have a key for both first_name & last_name or do some regex magic, which I can't do XD

Hope that helps :)


간단한 변경 가능한 솔루션으로 splice를 연속으로 두 번 호출 할 수 있습니다.

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

반면에 간단한 불변 솔루션은 슬라이스를 사용할 수 있습니다.이 메서드는 원래 배열을 변경하지 않고 섹션의 복사본을 반환하기 때문입니다.

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

이 방법으로 작업 순서 변경

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

나는 이것이 효과가 있기를 바랍니다

참고 URL : https://stackoverflow.com/questions/2440700/reordering-arrays

반응형