programing

어레이에 값을 추가하는 가장 효율적인 방법

goodsources 2022. 9. 11. 20:12
반응형

어레이에 값을 추가하는 가장 효율적인 방법

크기가 다음과 같은 어레이가 있다고 가정합니다.N(어디서)N > 0O(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);
// => [0, 1, 2, 3, 4]
console.log({a});

[편집]

jsPerf 벤치마크에서는unshift어레이를 인플레이스(in-place)로 변경해도 괜찮다면 빅O 퍼포먼스가 다를 수 있지만 적어도 몇 개의 브라우저에서 상당히 빨라집니다.원래의 어레이를 정말로 뮤트 할 수 없는 경우는, 이하의 스니펫과 같은 처리를 실시합니다.이 스니펫은 솔루션보다 그다지 빠르지 않은 것 같습니다.

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

[편집 2]

완성도를 위해 OP의 예 대신 다음 함수를 사용할 수 있습니다.prependArray(...)어레이를 활용하다unshift(...)방법:

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

var x = [1, 2, 3];
var y = prepend(0, x);
// x => [1, 2, 3];
// y => [0, 1, 2, 3];
console.log({ x, y });

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. 그래서:

const newArray = [1, 2, 3].concat([4, 5]);
newArray; // [1, 2, 3, 4, 5]

그러나 oldArray의 사이즈는 O(N)입니다.그러나 수동으로 oldArray를 반복하는 것보다 효율적입니다.또, 상세한 것에 따라서는, 복수의 값을 부가하는 경우는, 각각의 값을 개별적으로 부가하는 것보다, 그것들을 먼저 어레이에 넣은 후, 마지막에 oldArray 를 조합하는 것이 좋기 때문에, 도움이 될 가능성이 있습니다.

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

어레이(어레이 a2)를 프리펜드 하는 경우는, 다음을 사용할 수 있습니다.

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

이전 배열을 보존해야 할 경우 이전 배열을 슬라이스하고 새 값을 슬라이스 시작 부분으로 이동합니다.

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 elems)의 경우, 리더는 푸시 방식과 함께 사이클을 실시합니다.대규모 어레이의 경우 Unshift 방식이 리더가 됩니다.

그러나 이 상황은 Chrome 브라우저에서만 발생합니다.파이어폭스에서 unshift는 놀라운 최적화 기능을 갖추고 있으며 모든 경우에 더 빠릅니다.

ES6 확산 속도는 모든 브라우저에서 100배 이상 느립니다.

https://jsbench.me/cgjfc79bgx/1

" "unshift는 새 배열의 길이만 반환합니다.처음에 요소를 추가하고 새 배열을 반환하려면 다음을 수행합니다.

let newVal = 'someValue';
let array = ['hello', 'world'];
[ newVal ].concat(array);

또는 단순히 산포 연산자와 함께:

[ newVal, ...array ]

이렇게 하면 원래 배열은 변경되지 않은 상태로 유지됩니다.

불변의 방법으로는 이것이 가장 좋은 방법일 것입니다.

const x = 1
const list = [2, 3, 4]
const newList = [x].concat(list) // [1, 2, 3, 4]

특별한 방법이 있습니다.

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]

임플레이스 프리펜딩의 예:

var A = [7,8,9]
var B = [1,2,3]

A.unshift(...B)

console.log(A) // [1,2,3,7,8,9]

방금 Chrome에서 4가지 알고리즘의 벤치마크를 실행했습니다.

인플레이스:

// 1) splice method
{
    let x = [8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44];
    const y = [5, 6, 99, 5, 3, 4];
    x.splice(0, 0, ...y); // 87'426 ops/s (but big variation of 35%)
    // x is [5, 6, 99, 5, 3, 4, 8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44]
}

// 2) unshift method
{
    let x = [8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44];
    const y = [5, 6, 99, 5, 3, 4];
    x.unshift(...y); // 69'471 ops/s
    // x is [5, 6, 99, 5, 3, 4, 8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44]
}

복사:

// 3) spread operator
{
    const x = [8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44];
    const y = [5, 6, 99, 5, 3, 4];
    const z = [...y, ...x]; // 17'118 ops/s
    // z is [5, 6, 99, 5, 3, 4, 8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44]
}

// 4) concat method
{
    const x = [8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44];
    const y = [5, 6, 99, 5, 3, 4];
    const z = y.concat(x); // 6'286 ops/s
    // z is [5, 6, 99, 5, 3, 4, 8, 4, 1, 4, 124, 1, 14, 11, 9, 100, 6, 44]
}

요약: 프리펜드를 원하는 경우 unshift와 스플라이스를 모두 사용할 수 있습니다.복사를 원하는 경우 스프레드 연산자를 선택하는 것이 가장 좋습니다.적어도 크롬에서는요.

언급URL : https://stackoverflow.com/questions/6195729/most-efficient-way-to-prepend-a-value-to-an-array

반응형