한 배열 위치에서 다른 배열 위치로 배열 요소 이동
배열 요소를 이동하는 방법을 알아내는 데 어려움을 겪고 있습니다. 예를 들면 다음과 같습니다.
var arr = [ 'a', 'b', 'c', 'd', 'e'];
'd'
이전 에 이동할 함수를 작성하려면 어떻게 해야 'b'
합니까?
또는 'a'
후 'c'
?
이동 후 나머지 요소의 색인을 업데이트해야합니다. 이것은 이동 후 첫 번째 예에서 arr [0] = 'a', arr [1] = 'd'arr [2] = 'b', arr [3] = 'c', arr [4] = '이자형'
이것은 매우 간단해야하지만 머리를 감쌀 수는 없습니다.
npm의 버전을 원한다면 array-move 가이 답변에 가장 가깝지만 동일한 구현은 아닙니다. 자세한 내용은 사용법 섹션을 참조하십시오. 이 답변의 이전 버전 (Array.prototype.move를 수정)은 npm의 array.prototype.move 에서 찾을 수 있습니다 .
이 기능으로 상당히 성공했습니다.
function array_move(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
};
// returns [2, 1, 3]
console.log(array_move([1, 2, 3], 0, 1));
마지막 return
은 테스트 목적으로 만 사용됩니다. splice
어레이에서 적절한 작업을 수행하므로 반환 할 필요가 없습니다. 확장하면이 작업 move
은 적절한 작업입니다. 이를 피하고 사본을 반환하려면을 사용하십시오 slice
.
코드 단계별 설명 :
- 경우
new_index
배열의 길이보다 큰 경우, 우리는 새로운 제대로 패드에 배열을 (나는 가정) 할undefined
의. 이 작은 스 니펫undefined
은 적절한 길이가 될 때까지 배열 을 밀어서이를 처리합니다 . - 그런 다음
arr.splice(old_index, 1)[0]
에서 이전 요소를 스 플라이 싱합니다.splice
접합 된 요소를 반환하지만 배열에 있습니다. 위의 예에서 이것은이었습니다[1]
. 따라서 해당 배열의 첫 번째 인덱스를 가져 와서 원시를 가져옵니다1
. - 그런 다음
splice
new_index 위치에이 요소를 삽입 하는 데 사용 합니다. 위의 배열을 위의 패딩했기 때문에new_index > arr.length
음수로 전달하는 것과 같은 이상한 일을하지 않는 한 올바른 위치에 나타납니다.
음수 지수를 설명하는 더 멋진 버전 :
function array_move(arr, old_index, new_index) {
while (old_index < 0) {
old_index += arr.length;
}
while (new_index < 0) {
new_index += arr.length;
}
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing purposes
};
// returns [1, 3, 2]
console.log(array_move([1, 2, 3], -1, -2));
어느 것이 array_move([1, 2, 3], -1, -2)
올바르게 설명해야합니까 (마지막 요소를 두 번째 위치에서 마지막 위치로 이동). 그 결과는이어야합니다 [1, 3, 2]
.
어느 쪽이든, 원래의 질문에, 당신은 할 것이다 array_move(arr, 0, 2)
위한 a
후 c
. 들어 d
전에 b
, 당신이 할 것입니다 array_move(arr, 3, 1)
.
JSPerf에서 찾은 라이너 하나입니다 ...
Array.prototype.move = function(from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};
읽는 것이 좋지만 (작은 데이터 세트에서) 성능을 원한다면 시도하십시오 ...
Array.prototype.move2 = function(pos1, pos2) {
// local variables
var i, tmp;
// cast input parameters to integers
pos1 = parseInt(pos1, 10);
pos2 = parseInt(pos2, 10);
// if positions are different and inside array
if (pos1 !== pos2 && 0 <= pos1 && pos1 <= this.length && 0 <= pos2 && pos2 <= this.length) {
// save element from position 1
tmp = this[pos1];
// move element down and shift other elements up
if (pos1 < pos2) {
for (i = pos1; i < pos2; i++) {
this[i] = this[i + 1];
}
}
// move element up and shift other elements down
else {
for (i = pos1; i > pos2; i--) {
this[i] = this[i - 1];
}
}
// put element from position 1 to destination
this[pos2] = tmp;
}
}
크레딧을받을 수 없습니다 . 모두 Richard Scarrott 로 가야합니다 . 이 성능 테스트 에서 더 작은 데이터 세트에 대한 스플 라이스 기반 방법을 능가합니다 . 그러나 Darwayne이 지적한 것처럼 더 큰 데이터 세트 에서는 속도가 상당히 느립니다 .
나는이 방법을 좋아한다. 간결하고 우아합니다.
function arraymove(arr, fromIndex, toIndex) {
var element = arr[fromIndex];
arr.splice(fromIndex, 1);
arr.splice(toIndex, 0, element);
}
참고 : 항상 배열 범위를 확인하십시오.
테스트 할 jsFiddle은 다음과 같습니다. https://jsfiddle.net/aq9Laaew/286055/
접합부 () 메소드는 추가 / 어레이 /로부터 항목을 제거하고, 복귀 제거 항목 (들).
참고 :이 방법은 원래 배열을 변경합니다. / w3schools /
Array.prototype.move = function(from,to){
this.splice(to,0,this.splice(from,1)[0]);
return this;
};
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(3,1);//["a", "d", "b", "c", "e"]
var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(0,2);//["b", "c", "a", "d", "e"]
함수가 체인 가능 하므로 다음과 같이 작동합니다.
alert(arr.move(0,2).join(','));
내 2c. 읽기 쉽고, 작동하고, 빠르며, 새로운 배열을 만들지 않습니다.
function move(array, from, to) {
if( to === from ) return array;
var target = array[from];
var increment = to < from ? -1 : 1;
for(var k = from; k != to; k += increment){
array[k] = array[k + increment];
}
array[to] = target;
return array;
}
배열 크기를 일정하게 유지하기 위해 이동 해야하는 항목 대신 무언가를 밀어 넣는 @Reid의 아이디어를 얻었습니다. 그것은 계산을 단순화합니다. 또한 빈 개체를 밀어 넣으면 나중에 고유하게 검색 할 수 있다는 이점이 있습니다. 두 객체가 동일한 객체를 참조 할 때까지 동일하지 않기 때문에 작동합니다.
({}) == ({}); // false
여기 소스 배열과 소스, 대상 인덱스를 취하는 함수가 있습니다. 필요한 경우 Array.prototype에 추가 할 수 있습니다.
function moveObjectAtIndex(array, sourceIndex, destIndex) {
var placeholder = {};
// remove the object from its initial position and
// plant the placeholder object in its place to
// keep the array length constant
var objectToMove = array.splice(sourceIndex, 1, placeholder)[0];
// place the object in the desired position
array.splice(destIndex, 0, objectToMove);
// take out the temporary object
array.splice(array.indexOf(placeholder), 1);
}
이것은 @Reid의 솔루션을 기반으로합니다. 외:
Array
프로토 타입을 변경하지 않습니다 .- 경계
undefined
에서 항목을 오른쪽으로 이동하면 항목이 생성되지 않고 항목이 가장 오른쪽 위치로 이동합니다.
함수:
function move(array, oldIndex, newIndex) {
if (newIndex >= array.length) {
newIndex = array.length - 1;
}
array.splice(newIndex, 0, array.splice(oldIndex, 1)[0]);
return array;
}
단위 테스트 :
describe('ArrayHelper', function () {
it('Move right', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 0, 1);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
})
it('Move left', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, 0);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
});
it('Move out of bounds to the left', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, -2);
assert.equal(array[0], 2);
assert.equal(array[1], 1);
assert.equal(array[2], 3);
});
it('Move out of bounds to the right', function () {
let array = [1, 2, 3];
arrayHelper.move(array, 1, 4);
assert.equal(array[0], 1);
assert.equal(array[1], 3);
assert.equal(array[2], 2);
});
});
선택적 매개 변수 가있는 내 라이너 ES6 솔루션 이 on
있습니다.
if (typeof Array.prototype.move === "undefined") {
Array.prototype.move = function(from, to, on = 1) {
this.splice(to, 0, ...this.splice(from, on))
}
}
제안한 첫 번째 솔루션의 적응 digiguru
매개 변수 on
는 from
이동하려는 요소의 수입니다 .
슬라이스 방법을 사용하여 원하는 순서대로 조각으로 새 배열을 만드는 방법이 있습니다.
예
var arr = [ 'a', 'b', 'c', 'd', 'e'];
var arr2 = arr.slice(0,1).concat( ['d'] ).concat( arr.slice(2,4) ).concat( arr.slice(4) );
- arr.slice (0,1)은 [ 'a']
- arr.slice (2,4)는 [ 'b', 'c']
- arr.slice (4)는 당신에게 [ 'e']를줍니다
도움 splice
이 Array
될 수 있는 방법 : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice
어레이를 적극적으로 재 인덱싱해야하므로 상대적으로 비쌀 수 있습니다.
기본 미적분을 구현하고 배열 요소를 한 위치에서 다른 위치로 이동하기위한 범용 함수를 만들 수 있습니다.
JavaScript의 경우 다음과 같습니다.
function magicFunction (targetArray, indexFrom, indexTo) {
targetElement = targetArray[indexFrom];
magicIncrement = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom);
for (Element = indexFrom; Element != indexTo; Element += magicIncrement){
targetArray[Element] = targetArray[Element + magicIncrement];
}
targetArray[indexTo] = targetElement;
}
자세한 설명은 "gloommatter"에서 "배열 요소 이동"을 확인하십시오.
http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html
불변의 이동 방법 (원래 배열을 변경하지 않은 방법)이 필요했기 때문에 @Reid의 허용 된 대답을 간단하게 Object.assign을 사용하여 배열의 복사본을 만들어 스플 라이스를 만들기 전에 적용했습니다.
Array.prototype.immutableMove = function (old_index, new_index) {
var copy = Object.assign([], this);
if (new_index >= copy.length) {
var k = new_index - copy.length;
while ((k--) + 1) {
copy.push(undefined);
}
}
copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
return copy;
};
여기에 작동중인 jsfiddle이 있습니다 .
Array.prototype.moveUp = function (value, by) {
var index = this.indexOf(value),
newPos = index - (by || 1);
if (index === -1)
throw new Error("Element not found in array");
if (newPos < 0)
newPos = 0;
this.splice(index, 1);
this.splice(newPos, 0, value);
};
Array.prototype.moveDown = function (value, by) {
var index = this.indexOf(value),
newPos = index + (by || 1);
if (index === -1)
throw new Error("Element not found in array");
if (newPos >= this.length)
newPos = this.length;
this.splice(index, 1);
this.splice(newPos, 0, value);
};
var arr = ['banana', 'curyWurst', 'pc', 'remembaHaruMembaru'];
alert('withiout changes= '+arr[0]+' ||| '+arr[1]+' ||| '+arr[2]+' ||| '+arr[3]);
arr.moveDown(arr[2]);
alert('third word moved down= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);
arr.moveUp(arr[2]);
alert('third word moved up= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);
http://plnkr.co/edit/JaiAaO7FQcdPGPY6G337?p=preview
여기에 대한 답변을 ECMAScript 6
기반 으로 불변의 솔루션을 구현했습니다 @Merc
.
const moveItemInArrayFromIndexToIndex = (array, fromIndex, toIndex) => {
if (fromIndex === toIndex) return array;
const newArray = [...array];
const target = newArray[fromIndex];
const inc = toIndex < fromIndex ? -1 : 1;
for (let i = fromIndex; i !== toIndex; i += inc) {
newArray[i] = newArray[i + inc];
}
newArray[toIndex] = target;
return newArray;
};
변수 이름은 짧아 질 수 있으며, 긴 이름을 사용하여 코드 자체를 설명 할 수 있습니다.
Array.move.js
요약
배열 내에서 요소를 이동하여 이동 된 요소가 포함 된 배열을 반환합니다.
통사론
array.move(index, howMany, toIndex);
매개 변수
index : 요소를 이동할 인덱스. 음수이면 색인 이 끝에서 시작됩니다.
howMany : 인덱스 에서 이동할 요소 수 .
toIndex : 이동 한 요소를 배치 할 배열의 인덱스입니다. 음수이면 toIndex 가 끝에서 시작됩니다.
용법
array = ["a", "b", "c", "d", "e", "f", "g"];
array.move(3, 2, 1); // returns ["d","e"]
array; // returns ["a", "d", "e", "b", "c", "f", "g"]
폴리 필
Array.prototype.move || Object.defineProperty(Array.prototype, "move", {
value: function (index, howMany, toIndex) {
var
array = this,
index = parseInt(index) || 0,
index = index < 0 ? array.length + index : index,
toIndex = parseInt(toIndex) || 0,
toIndex = toIndex < 0 ? array.length + toIndex : toIndex,
toIndex = toIndex <= index ? toIndex : toIndex <= index + howMany ? index : toIndex - howMany,
moved;
array.splice.apply(array, [toIndex, 0].concat(moved = array.splice(index, howMany)));
return moved;
}
});
작고 먼 거리를 이동할 때 두 가지를 결합하여 조금 더 잘 작동했습니다. 나는 상당히 일관된 결과를 얻지 만, 아마도 다른 사람과는 다른 크기로 다르게 작동하도록 똑똑한 사람이 약간 조정할 수 있습니다.
거리를 좁힐 때 다른 방법을 사용하면 스플 라이스를 사용하는 것보다 훨씬 빠릅니다 (x10). 배열 길이에 따라 변경 될 수 있지만 큰 배열의 경우에는 해당됩니다.
function ArrayMove(array, from, to) {
if ( Math.abs(from - to) > 60) {
array.splice(to, 0, array.splice(from, 1)[0]);
} else {
// works better when we are not moving things very far
var target = array[from];
var inc = (to - from) / Math.abs(to - from);
var current = from;
for (; current != to; current += inc) {
array[current] = array[current + inc];
}
array[to] = target;
}
}
http://jsperf.com/arraymove-many-sizes
이 버전은 모든 목적에 이상적이지는 않으며 모든 사람이 쉼표 표현식을 좋아하지는 않지만 순수한 표현을 가진 새로운 라이너를 만들어 새로운 사본을 만듭니다.
const move = (from, to, ...a) => (a.splice(to, 0, ...a.splice(from, 1)), a)
약간의 성능 향상 버전은 이동이 필요하지 않은 경우 입력 배열을 반환하며, 배열이 변경되지 않으므로 여전히 불변의 사용이 가능하며 순수한 표현입니다.
const move = (from, to, ...a) =>
from === to
? a
: (a.splice(to, 0, ...a.splice(from, 1)), a)
둘 중 하나의 호출은
const shuffled = move(fromIndex, toIndex, ...list)
즉, 새로운 사본을 생성하기 위해 확산에 의존합니다. 고정 된 arity 3 move
을 사용하면 단일 표현식 속성이나 비파괴적인 특성 또는의 성능 이점이 위태로워집니다 splice
. 다시 말하지만, 프로덕션 사용에 대한 제안보다 몇 가지 기준을 충족시키는 예가 더 많습니다.
나는 @Reid 의 좋은 대답을 사용 했지만 배열의 끝에서 한 단계 더 나아가 요소를 루프 에서와 같이 처음으로 이동하는 데 어려움을 겪었습니다 . 예를 들어 [ 'a', 'b', 'c']는 .move (2,3)를 호출하여 [ 'c', 'a', 'b']가되어야합니다.
new_index> = this.length의 경우를 변경하여이를 달성했습니다.
Array.prototype.move = function (old_index, new_index) {
console.log(old_index + " " + new_index);
while (old_index < 0) {
old_index += this.length;
}
while (new_index < 0) {
new_index += this.length;
}
if (new_index >= this.length) {
new_index = new_index % this.length;
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
Array 프로토 타입을 가지고 노는 것은 많은 장소에서 ( Array.prototype에 커스텀 함수 추가 ) 언급되어 있습니다. 어쨌든 다양한 게시물에서 최고를 결합했습니다. 나는 현대 Javascript를 사용하여 이것을 제공했습니다.
Object.defineProperty(Array.prototype, 'immutableMove', {
enumerable: false,
value: function (old_index, new_index) {
var copy = Object.assign([], this)
if (new_index >= copy.length) {
var k = new_index - copy.length;
while ((k--) + 1) { copy.push(undefined); }
}
copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
return copy
}
});
//how to use it
myArray=[0, 1, 2, 3, 4];
myArray=myArray.immutableMove(2, 4);
console.log(myArray);
//result: 0, 1, 3, 4, 2
희망은 누구에게나 유용 할 수 있습니다
Reid의 훌륭한 답변에 덧붙여서 (그리고 내가 말할 수 없기 때문에); 모듈러스를 사용하여 음수 지수와 너무 큰 지수를 "롤오버"할 수 있습니다.
function array_move(arr, old_index, new_index) {
new_index =((new_index % arr.length) + arr.length) % arr.length;
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
}
// returns [2, 1, 3]
console.log(array_move([1, 2, 3], 0, 1));
let ar = ['a', 'b', 'c', 'd'];
function change( old_array, old_index , new_index ){
return old_array.map(( item , index, array )=>{
if( index === old_index ) return array[ new_index ];
else if( index === new_index ) return array[ old_index ];
else return item;
});
}
let result = change( ar, 0, 1 );
console.log( result );
결과:
["b", "a", "c", "d"]
const move = (from, to, ...a) =>from === to ? a : (a.splice(to, 0, ...a.splice(from, 1)), a);
const moved = move(0, 2, ...['a', 'b', 'c']);
console.log(moved)
참고 URL : https://stackoverflow.com/questions/5306680/move-an-array-element-from-one-array-position-to-another
도와주세요.
'development' 카테고리의 다른 글
부모와 커밋을 어떻게 다른가요? (0) | 2020.02.17 |
---|---|
XML 문서를 역 직렬화하는 방법 (0) | 2020.02.17 |
Docker 컨테이너의 런타임 성능 비용은 얼마입니까? (0) | 2020.02.17 |
데이터베이스에 비밀번호를 저장하는 가장 좋은 방법 (0) | 2020.02.17 |
배경 이미지에 CSS 필터를 적용하는 방법 (0) | 2020.02.17 |