Programing

자바 스크립트에서 배열의 길이를 초기화하는 방법은 무엇입니까?

lottogame 2020. 2. 16. 19:13
반응형

자바 스크립트에서 배열의 길이를 초기화하는 방법은 무엇입니까?


JavaScript의 배열 ( w3schoolsdevguru 포함)에서 읽은 대부분의 자습서 var test = new Array(4);구문을 사용하여 Array 생성자에 정수를 전달하여 특정 길이의 배열을 초기화 할 수 있다고 제안 합니다.

내 js 파일 에서이 구문을 자유롭게 사용한 후 jsLint를 통해 파일 중 하나를 실행 했으며 놀라웠 습니다.

오류 : 1 행 문자 22의 문제 : ')'이 (가) 예상되었지만 '4'가 표시되었습니다.
var test = new Array (4);
1 행 문자 23의 문제점 : ';'예상 대신 ')'를 보았습니다.
var test = new Array (4);
1 행 문자 23의 문제점 : 식별자를 예상하고 대신 ')'를 보았습니다.

jsLint의 동작에 대한 설명을 읽은 후에 는 jsLint가 실제로 new Array()구문을 좋아하지 않는 것처럼 보이며 대신 []배열을 선언 할 때 선호 합니다.

몇 가지 질문이 있습니다. 먼저 왜? new Array()구문을 대신 사용하여 위험을 감수하고 있습니까? 알아야 할 브라우저 비 호환성이 있습니까? 둘째, 대괄호 구문으로 전환하면 배열을 선언하고 길이를 한 줄로 설정하는 방법이 있습니까? 아니면 다음과 같이해야합니다.

var test = [];
test.length = 4;

  1. 왜 길이를 초기화하고 싶습니까? 이론적으로는 이것이 필요하지 않습니다. length배열 을 사용 하는지 여부를 찾기 위해 를 사용하는 모든 테스트 에서 배열이 비어 있지 않은 것으로보고 하기 때문에 혼동 될 수 있습니다 .
    일부 테스트에 따르면 나중에 배열이 채워지면 큰 배열의 초기 길이를 설정하는 것이 더 효율적일 있지만 성능 향상 (있는 경우)은 브라우저마다 다릅니다.

  2. new Array()생성자가 모호하기 때문에 jsLint는 마음에 들지 않습니다 .

    new Array(4);
    

    길이가 4 인 빈 배열 만듭니다.

    new Array('4');
    

    값을 포함 하는 배열 만듭니다 '4'.

귀하의 의견과 관련하여 : JS에서는 배열의 길이를 초기화 할 필요가 없습니다. 동적으로 성장합니다. 예를 들어 길이를 일부 변수에 저장할 수 있습니다.

var data = [];
var length = 5; // user defined length

for(var i = 0; i < length; i++) {
    data.push(createSomeObject());
}

  • Array(5) 길이가 5이지만 값이없는 배열을 제공하므로 반복 할 수 없습니다.

  • Array.apply(null, Array(5)).map(function () {}) 길이가 5이고 값으로 정의되지 않은 배열을 제공하므로 반복 할 수 있습니다.

  • Array.apply(null, Array(5)).map(function (x, i) { return i; }) 길이가 5이고 값이 0,1,2,3,4 인 배열을 제공합니다.

  • Array(5).forEach(alert)아무것도하지 않습니다, Array.apply(null, Array(5)).forEach(alert)당신에게 5 개의 경고를줍니다

  • ES6Array.from당신이 사용할 수 있도록 지금 우리에게 제공Array.from(Array(5)).forEach(alert)

  • 당신이 특정 값으로 초기화하려면, 다음이 좋은 알고에 ...
    Array.from('abcde'), Array.from('x'.repeat(5))
    또는Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]


ES2015.fill()사용하면 이제 간단하게 수행 할 수 있습니다.

// `n` is the size you want to initialize your array
// `0` is what the array will be filled with (can be any other value)
Array(n).fill(0)

어느 것보다 훨씬 간결합니다 Array.apply(0, new Array(n)).map(i => value)

0in 을 제거하고 .fill()인수없이 실행할 수 있으며 배열을로 채 웁니다 undefined. ( 그러나 이것은 Typescript에서 실패합니다 )


가장 짧은 :

[...Array(1000)]

[...Array(6)].map(x=>0);

// [0, 0, 0, 0, 0, 0]

또는

Array(6).fill(0);

// [0, 0, 0, 0, 0, 0]

참고 : 빈 슬롯을 반복 할 수 없습니다 Array(4).forEach( (_,i) => {} )

또는

Array(6).fill(null).map( (x,i) => i );

// [0, 1, 2, 3, 4, 5]

( 활자체 안전 )


중첩 배열 만들기

직관적 으로 2D 배열을 fill만들 때 새 인스턴스를 만들어야합니다. 그러나 실제로 일어날 것은 동일한 배열이 참조로 저장된다는 것입니다.

var a = Array(3).fill([6]); 
// [[6], [6], [6]]

a[ 0 ].push( 9 );
// [[6,9], [6,9], [6,9]]

해결책

var a = [...Array(3)].map(x=>[]); 

a[ 0 ].push( 4, 2 );
// [[4,2], [ ], [ ]]

따라서 3x2 배열은 다음과 같습니다.

[...Array(3)].map(x=>Array(2).fill(0));

// [ [0,0] ,
//   [0,0] ,
//   [0,0] ]

체스 판 초기화

var Chessboard = [...Array( 8 )].map( (x,j) =>
    Array( 8 ).fill( null ).map( (y,i) =>
        `${ String.fromCharCode( 65 + i ) }${ 8 - j }`));

// [ [ A8,B8,C8,D8,E8,F8,G8,H8 ],
//   [ A7,B7,C7,D7,E7,F7,G7,H7 ],
//   [ A6,B6,C6,D6,E6,F6,G6,H6 ],
//   [ A5,B5,C5,D5,E5,F5,G5,H5 ],
//   [ A4,B4,C4,D4,E4,F4,G4,H4 ],
//   [ A3,B3,C3,D3,E3,F3,G3,H3 ],
//   [ A2,B2,C2,D2,E2,F2,G2,H2 ],
//   [ A1,B1,C1,D1,E1,F1,G1,H1 ] ]

ES6의 소개 Array.from당신은을 만들 수 있습니다 Array어떤에서 "같은 배열" 또는 반복 가능 객체는 객체 :

Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

이 경우 "배열 형" 객체 {length: 10}의 최소 ​​정의, 속성이 정의 된 빈 객체를 나타 냅니다.length

Array.from 결과 배열에 두 번째 인수를 매핑 할 수 있습니다.


길이 속성을 4로 초기화합니다.

var x = [,,,,];

한 줄로 길이를 설정할 수있는 기능적 솔루션이 없다는 것이 놀랍습니다. 다음은 UnderscoreJS를 기반으로합니다.

var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);

위에서 언급 한 이유로 배열을 특정 값으로 초기화하지 않으려는 경우이 작업을 수행하지 마십시오. Lo-dash 및 Lazy를 포함하여 범위를 구현하는 다른 라이브러리가 있으며, 이는 다른 성능 특성을 가질 수 있습니다.


(이것은 아마도 의견으로 더 좋았지 만 너무 길었습니다)

그래서 이것을 읽은 후에 나는 사전 할당이 실제로 더 빠르면 궁금했습니다. 이론적으로는 그렇게해야하기 때문입니다. 그러나이 블로그는 http://www.html5rocks.com/en/tutorials/speed/v8/ 에 대한 조언을 제공했습니다 .

그래도 확실하지 않아 테스트에 넣었습니다. 그리고 실제로는 느려 보입니다.

var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
    temp[i]=i;
}
console.log(Date.now()-time);


var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
    temp2[i] = i;
}
console.log(Date.now()-time); 

이 코드는 몇 번의 캐주얼 실행 후 다음을 생성합니다.

$ node main.js 
9
16
$ node main.js 
8
14
$ node main.js 
7
20
$ node main.js 
9
14
$ node main.js 
9
19

var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6

다른 해결책이 있습니다.

var arr = Array.apply( null, { length: 4 } );
arr;  // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4

첫 번째 인수 apply()는 this 객체 바인딩이며 여기서는 신경 쓰지 않으므로로 설정합니다 null.

Array.apply(..)Array(..)함수를 호출하고 { length: 3 }객체 값을 인수로 분산시킵니다 .


사람들은 아직 예전 습관을 포기하지 마십시오. 메모리를 한 번 할당 한 다음 해당 어레이의 항목을 사용하여 작업하고 (오래된대로) 여러 번 할당 할 때 (이는 제안 된 다른 방법으로 시스템에서 수행하는 작업) 필연적으로 속도에 큰 차이가 있습니다. .

더 큰 배열로 멋진 것을 원할 때까지 이것은 물론 중요하지 않습니다. 그럼 그렇습니다.

배열의 초기 용량을 설정하는 현재 JS에는 여전히 옵션이없는 것처럼 보이므로 다음을 사용합니다 ...

var newArrayWithSize = function(size) {
  this.standard = this.standard||[];
  for (var add = size-this.standard.length; add>0; add--) {
   this.standard.push(undefined);// or whatever
  }
  return this.standard.slice(0,size);
}

다음과 같은 장단점이 있습니다.

  • 이 메소드는 다른 함수가 함수를 처음 호출하는 데 걸리는 시간이 더 길지만, 더 큰 배열을 요구하지 않는 한 나중에 호출하는 데는 시간이 거의 없습니다.
  • standard배열은 영구적으로 요구 한 최대 규모의 배열만큼 공간으로 확보 않습니다.

그러나 그것이 당신이하고있는 일에 적합하다면 대가를받을 수 있습니다. 비공식적 인 타이밍

for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}

꽤 빠른 속도로 (n = 1000000이면 약 5 초가 걸리면 10000의 경우 약 50ms)

for (var n=10000;n>0;n--) {
  var b = [];for (var add=10000;add>0;add--) {
    b.push(undefined);
  }
}

1 분 이상 (동일한 크롬 콘솔에서 10000의 경우 약 90 초 또는 약 2000 배 느림) 그것은 할당뿐만 아니라 10000 푸시, for 루프 등입니다.


배열 생성자는 모호한 구문 을 가지고 있으며 JSLint는 결국 감정을 상하게합니다.

또한 예제 코드가 손상되면 두 번째 var문에서가 발생합니다 SyntaxError. length배열 의 속성 설정하므로 다른 속성 test필요하지 않습니다 var.

당신의 선택에 따라 array.length, 유일한 "깨끗한"것입니다. 질문은, 왜 먼저 크기를 설정해야합니까? 해당 종속성을 제거하기 위해 코드를 리팩터링하십시오.


위에서 설명한 것처럼 사용 new Array(size)은 다소 위험합니다. 직접 사용하는 대신 "배열 생성기 기능"안에 배치하십시오. 이 기능에 버그가 없는지 쉽게 확인할 수 있으며 new Array(size)직접 호출 위험이 없습니다 . 또한 선택적 초기 값을 지정할 수 있습니다. createArray함수는 정확히 다음을 수행합니다.

function createArray(size, defaultVal) {
    var arr = new Array(size);
    if (arguments.length == 2) {
        // optional default value
        for (int i = 0; i < size; ++i) {
            arr[i] = defaultVal;
        }
    }
    return arr;
}

Array의 길이가 일정하다고 가정합니다. Javascript에서 이것은 우리가하는 일입니다.

const intialArray = new Array(specify the value);


다음을 사용하여 배열 길이를 설정할 수 있습니다 array.length = youValue

그래서 그것은

var myArray = [];
myArray.length = yourValue;

사용하지 말아야 할 이유 new Array는 다음 코드에 의해 설명됩니다.

var Array = function () {};

var x = new Array(4);

alert(x.length);  // undefined...

일부 다른 코드 배열 변수를 엉망. 나는 누군가가 그런 코드를 작성할 것이라고 조금은 알고 있지만 여전히 ...

또한 Felix King이 말했듯이 인터페이스가 약간 일치하지 않아 추적하기 어려운 버그가 발생할 수 있습니다.

길이가 x 인 배열이 정의되지 않은 채 채워진 경우 다음과 같이 new Array(x)할 수 있습니다.

var x = 4;
var myArray = [];
myArray[x - 1] = undefined;

alert(myArray.length); // 4

참고 URL : https://stackoverflow.com/questions/4852017/how-to-initialize-an-arrays-length-in-javascript



반응형