어레이에 값을 추가하는 가장 효율적인 방법
크기가 다음과 같은 어레이가 있다고 가정합니다.N
(어디서)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);
// => [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
'programing' 카테고리의 다른 글
SQL INSERT 문에 Python dict 사용 (0) | 2022.09.11 |
---|---|
변경 전 선택(드롭다운) 값을 가져오는 중 (0) | 2022.09.11 |
PHP의 문자열에서 각 행에 걸쳐 반복 (0) | 2022.09.11 |
MySQL의 DATETIME 필드에서 날짜만 선택하는 방법 (0) | 2022.09.11 |
Vue는 생성자가 아닙니다. (0) | 2022.09.11 |