배열 재정렬


98

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

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

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


3
"작동하지 않음"은 무엇을 의미합니까? 오류가 발생합니까, 아무것도 변경되지 않습니까? 의도하지 않은 방식으로 배열이 변경됩니까? 나에게 합리적으로 보입니다.
Jacob Mattison

답변:


222

구문 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

도표:

알고리즘 다이어그램


17
이것은 좋은 대답이며 splice () 내의 splice ()는 작업을 잘 수행합니다. 그러나 Array 프로토 타입에 move () 메서드를 추가하는 것을 "Monkey Patching"이라고하며 일반적으로 나쁜 습관으로 간주됩니다. stackoverflow.com/questions/5741877/...
아론 아 치 칼리에게

20

인덱스를 알고 있다면 다음과 같은 간단한 기능으로 요소를 쉽게 바꿀 수 있습니다.

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

배열 인덱스는 배열 객체의 속성 일 뿐이므로 값을 바꿀 수 있습니다.


감사합니다, @CMS. 예를 들어 3 번째 개체를 1 번째 위치로 바꾸면 1을 2로, 2를 3으로 1로 바꾸고 싶습니다.
Peri

13

관심있는 사람들을위한 불변 버전은 다음과 같습니다.

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

안녕하세요, 위의 답변에 비해이 기능의 이점을 설명해 주시겠습니까?
Xogno

1
이 솔루션은 원래 요소를 수정하지 않지만 항목이 이동되는 새 배열을 반환합니다.
chmanie

7

요소를 제거 할 때 스플 라이스 호출의 첫 번째 매개 변수로 2를 1로 변경합니다.

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

1
playlist.splice (2,0, tmp [0]); 권리?
Crisboot

7

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]

1
이것은 두 요소의 위치를 ​​바꿉니다. 재주문에 대한 질문입니다.
BY

5

레코드가 현재 어디에 있는지 모르는 경우 항상 정렬 방법을 사용할 수 있습니다.

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

1
어떨까요return +(a.artist == "Lalo Schifrin")
Funkodebat

2
@Funko는 장황함보다 간결함을 선호한다면 그렇게 할 수 있습니다.
Andy E

2

편집 : 그의 대답이 먼저 왔 으므로 Andy의 대답 을 확인하십시오. 이것은 전적으로 그의 확장입니다.

나는 이것이 오래된 질문이라는 것을 알고 있지만 포함하는 것이 가치가 있다고 생각합니다 Array.prototype.sort().

다음 은 링크와 함께 MDN의 예입니다.

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

정렬 순서를 정의하는 함수를 지정합니다. 생략하면 각 요소의 문자열 변환에 따라 각 문자의 유니 코드 코드 포인트 값에 따라 배열이 정렬됩니다.

이름으로 주문하신 것으로 나타났습니다.

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_name& 둘 다에 대한 키가 last_name있거나 정규식 마법을 수행해야합니다.

도움이되기를 바랍니다 :)


이것은 이 답변 에 대한 편집 또는 의견이어야합니다 .
자레드 스미스

@JaredSmith 죄송합니다! 나는 그의 대답을 보지 못했다. 나는 그의 질문을 편집하기에 충분한 포인트 나 다른 것이 없으며,이 모든 정보가 코멘트에 추가되어야한다고 생각하지 않습니다. 그래서 누군가 그의 질문을 편집 할 때까지 나는 이것이 Andy E의 대답에 대한 확장이라고 덧붙일 것입니다.
Jaacko Torus

나는 :) 지금은 괜찮아요 생각
자레드 스미스에게


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

0

간단한 변경 가능한 솔루션으로 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)]

-2

이 방법으로 작업 순서 변경

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

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


1
이것은 기존 답변에 무엇을 추가합니까?
Jared Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.