[javascript] 배열에 값을 추가하는 가장 효율적인 방법

크기가 N(where N > 0) 인 배열이 있다고 가정하면 O (N + 1) 단계가 필요하지 않은 배열 앞에 더 효율적인 방법이 있습니까?

코드에서 본질적으로 현재하고있는 것은

function prependArray(value, oldArray) {
  var newArray = new Array(value);

  for(var i = 0; i < oldArray.length; ++i) {
    newArray.push(oldArray[i]);
  }

  return newArray;
}



답변

big-O 측면에서 더 효율적인지 확실하지 않지만 unshift방법을 사용하는 것이 더 간결합니다.

var a = [1, 2, 3, 4];
a.unshift(0);
a; // => [0, 1, 2, 3, 4]

[편집하다]

jsPerf 벤치 마크 는 어레이를 제자리에서 수정해도 괜찮다 unshift 다른 big-O 성능에 관계없이 적어도 몇 개의 브라우저에서 상당히 빠르다 는 것을 보여줍니다 . 원래 배열을 변경할 수 없다면 아래 스 니펫과 같은 작업을 수행 할 수 있습니다. 솔루션보다 훨씬 빠르지 않은 것 같습니다.

a.slice().unshift(0); // Use "slice" to avoid mutating "a".

[편집 2]

완전성 prependArray(...)을 위해 OP의 예제 대신 다음 함수를 사용 하여 Array unshift(...)메소드를 활용할 수 있습니다 .

function prepend(value, array) {
  var newArray = array.slice();
  newArray.unshift(value);
  return newArray;
}

var x = [1, 2, 3];
var y = prepend(0, x);
y; // => [0, 1, 2, 3];
x; // => [1, 2, 3];


답변

ES6에서는 이제 스프레드 연산자 를 사용하여 새 요소를 원래 요소 앞에 삽입하여 새 배열을 만들 수 있습니다.

// Prepend a single item.
const a = [1, 2, 3];
console.log([0, ...a]);

// Prepend an array.
const a = [2, 3];
const b = [0, 1];
console.log([...b, ...a]);

2018-08-17 업데이트 : 성능

나는이 대답이 더 기억하기 쉽고 간결한 대안 구문을 제시하기 위해 의도했습니다. 일부 벤치 마크 ( 이 다른 답변 참조 )에 따르면이 구문은 상당히 느립니다. 루프에서 이러한 많은 작업을 수행하지 않는 한 이것은 중요하지 않을 것입니다.


답변

다른 배열 앞에 배열을 추가하는 경우을 사용하는 것이 더 효율적 concat입니다. 그래서:

var newArray = values.concat(oldArray);

그러나 이것은 oldArray 크기에서 여전히 O (N)입니다. 여전히 oldArray를 수동으로 반복하는 것보다 효율적입니다. 또한 세부 정보에 따라 많은 값을 앞에 추가하려는 경우 각 값을 개별적으로 추가하는 대신 배열에 먼저 배치 한 다음 끝에 oldArray를 연결하는 것이 좋습니다.

배열은 첫 번째 요소가 고정 된 위치에있는 연속 메모리에 저장되므로 oldArray 크기에서 O (N)보다 더 나은 방법은 없습니다. 첫 번째 요소 앞에 삽입하려면 다른 모든 요소를 ​​이동해야합니다. 이 문제를 해결할 방법이 필요하면 @GWW가 말한 것을 수행하고 연결된 목록 또는 다른 데이터 구조를 사용하십시오.


답변

배열 (a1에 배열 a2)을 추가하려면 다음을 사용할 수 있습니다.

var a1 = [1, 2];
var a2 = [3, 4];
Array.prototype.unshift.apply(a1, a2);
console.log(a1);
// => [3, 4, 1, 2]


답변

f 이전 배열을 유지하고 이전 배열을 슬라이스하고 새 값을 슬라이스의 시작 부분으로 이동하지 않아야합니다.

var oldA=[4,5,6];
newA=oldA.slice(0);
newA.unshift(1,2,3)

oldA+'\n'+newA

/*  returned value:
4,5,6
1,2,3,4,5,6
*/


답변

나는 여러 가지 다른 방법에 대한 새로운 테스트를 받았습니다. 소형 어레이 (<1000 elem)의 경우 리더는 푸시 방식과 결합 된 사이클을위한 것입니다. 거대한 배열의 경우 Unshift 방법이 리더가됩니다.

그러나이 상황은 Chrome 브라우저에만 해당됩니다. Firefox에서 unshift는 뛰어난 최적화 기능을 갖추고 있으며 모든 경우에 더 빠릅니다.

ES6 스프레드는 모든 브라우저에서 100 배 이상 느립니다.

https://jsbench.me/cgjfc79bgx/1


답변

특별한 방법이 있습니다 :

a.unshift(value);

그러나 배열에 여러 요소를 추가하려면 그러한 방법을 사용하는 것이 더 빠릅니다.

var a = [1, 2, 3],
    b = [4, 5];

function prependArray(a, b) {
    var args = b;
    args.unshift(0);
    args.unshift(0);
    Array.prototype.splice.apply(a, args);
}

prependArray(a, b);
console.log(a); // -> [4, 5, 1, 2, 3]