[javascript] 1… N을 포함하는 배열을 만드는 방법

1에서 N까지의 JavaScript 배열을 만드는 아래의 대안을 찾고 있습니다. 여기서 N은 런타임에만 알려져 있습니다.

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}

나에게 루프없이 이것을하는 방법이 있어야한다고 생각합니다.



답변

내가 당신이 무엇을 얻는다면, 1..n당신은 나중에 반복 할 수 있는 숫자 배열을 원합니다 .

이것이 당신이 필요한 전부라면, 대신 할 수 있습니까?

var foo = new Array(45); // create an empty array with length 45

그런 다음 사용하고 싶을 때 … (예를 들어 최적화되지 않은)

for(var i = 0; i < foo.length; i++){
  document.write('Item: ' + (i + 1) + ' of ' + foo.length + '<br/>');
}

예를 들어 배열에 아무것도 저장할 필요가 없다면 반복 할 수있는 올바른 길이의 컨테이너가 필요합니다 … 더 쉬울 수 있습니다.

http://jsfiddle.net/3kcvm/ 에서 실제로 확인하십시오.


답변

ES6에서는 Array from ()keys () 메소드를 사용합니다.

Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

스프레드 연산자를 사용하는 더 짧은 버전 .

[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


답변

그렇게 할 수 있습니다 :

var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)

결과 : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

또는 임의의 값으로 :

Array.apply(null, {length: N}).map(Function.call, Math.random)

결과 : [0.7082694901619107, 0.9572225909214467, 0.8586748542729765, 0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.8377588465809822, 0.5577575915958732, 0.16363654541783035]

설명

먼저,는를 반환하는 Number.call(undefined, N)것과 같습니다 . 우리는 나중에 그 사실을 사용할 것입니다.Number(N)N

Array.apply(null, [undefined, undefined, undefined])Array(undefined, undefined, undefined)3 요소 배열을 생성하고 undefined각 요소에 할당하는와 같습니다 .

이것을 N 요소로 일반화 할 수 있습니까? Array()작동 방식을 고려하십시오 .

function Array() {
    if ( arguments.length == 1 &&
         'number' === typeof arguments[0] &&
         arguments[0] >= 0 && arguments &&
         arguments[0] < 1 << 32 ) {
        return [  ];  // array of length arguments[0], generated by native code
    }
    var a = [];
    for (var i = 0; i < arguments.length; i++) {
        a.push(arguments[i]);
    }
    return a;
}

ECMAScript를 5부터 , Function.prototype.apply(thisArg, argsArray)또한 두 번째 매개 변수로서 오리 입력 어레이 형상 물체를 수용한다. 우리가 호출 Array.apply(null, { length: N })하면 실행됩니다

function Array() {
    var a = [];
    for (var i = 0; i < /* arguments.length = */ N; i++) {
        a.push(/* arguments[i] = */ undefined);
    }
    return a;
}

이제 각 요소가로 설정된 N 요소 배열이 undefined있습니다. 호출하면 .map(callback, thisArg)각 요소는의 결과로 설정됩니다 callback.call(thisArg, element, index, array). 따라서 [undefined, undefined, …, undefined].map(Number.call, Number)각 요소를에 매핑합니다 (Number.call).call(Number, undefined, index, array). 이는 Number.call(undefined, index, array)앞에서 살펴본 바와 같이로 평가됩니다 index. 이것으로 요소가 인덱스와 같은 배열을 완성합니다.

Array.apply(null, {length: N})그냥 대신에 문제를 겪고 Array(N)있습니까? 결국 두 표현식 모두 정의되지 않은 요소로 구성된 N 요소 배열이됩니다. 차이점은 이전 표현식에서, 각각의 요소가 명시되어있다 설정 후자에서, 각각의 요소가 설정되지 않았던 반면, 정의에 관한 것이다. 의 문서에 따르면 .map():

callback값이 할당 된 배열의 인덱스에 대해서만 호출됩니다. 삭제되었거나 값이 할당되지 않은 인덱스에 대해서는 호출되지 않습니다.

따라서 Array(N)충분하지 않습니다. Array(N).map(Number.call, Number)초기화되지 않은 길이 N의 배열이 생성됩니다 .

적합성

이 기술은 Function.prototype.apply()ECMAScript 5 에 지정된 동작에 의존하기 때문에 Chrome 14 및 Internet Explorer 9와 같은 ECMAScript 5 이전 브라우저 에서는 작동하지 않습니다 .


답변

ES6를 사용하는 여러 가지 방법

스프레드 연산자 ( ...) 및 키 방법 사용

[ ...Array(N).keys() ].map( i => i+1);

채우기 /지도

Array(N).fill().map((_, i) => i+1);

배열

Array.from(Array(N), (_, i) => i+1)

Array.from 및 { length: N }해킹

Array.from({ length: N }, (_, i) => i+1)

일반화 된 양식에 대한 참고 사항

변경하여 거의 원하는 값으로 초기화 캔 생산 배열 위의 모든 형태 i+1(예 : 요구 표현 i*2, -i, 1+i*2, i%2등). 어떤 함수로 표현을 표현할 수 있다면 f첫 번째 형태는 단순히

[ ...Array(N).keys() ].map(f)

예 :

Array.from({length: 5}, (v, k) => k+1);
// [1,2,3,4,5]

이 배열로 초기화되기 때문에, undefined각 위치에서의 값이 v 될 것이다undefined

모든 양식을 보여주는 예

사용자 정의 이니셜 라이저 기능을 사용하는보다 일반적인 예 f:

[ ...Array(N).keys() ].map((i) => f(i))

또는 더 간단한

[ ...Array(N).keys() ].map(f)


답변

배열은 본질적으로 길이를 관리합니다. 순회하면 인덱스를 메모리에 보관하고 해당 시점에서 참조 할 수 있습니다. 임의의 인덱스를 알아야 할 경우이 indexOf방법을 사용할 수 있습니다.

이것은 당신의 필요에 따라 특정 크기의 배열을 선언하고 싶을 수도 있습니다.

var foo = new Array(N);   // where N is a positive integer

/* this will create an array of size, N, primarily for memory allocation,
   but does not create any defined values

   foo.length                                // size of Array
   foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/

ES6

확산

스프레드 연산자 ( ...)와 keys메서드를 사용하면 인덱스를 생성하기 위해 N 크기의 임시 배열을 만든 다음 변수에 할당 할 수있는 새 배열을 만들 수 있습니다.

var foo = [ ...Array(N).keys() ];

채우기 /지도

먼저 필요한 배열의 크기를 만들고 정의되지 않은 채로 채우고 map각 요소를 색인으로 설정 하는을 사용하여 새 배열을 만들 수 있습니다 .

var foo = Array(N).fill().map((v,i)=>i);

배열

이것은 N 크기의 길이로 초기화되고 한 번에 배열을 채우는 것입니다.

Array.from({ length: N }, (v, i) => i)

위의 예제에서 주석과 혼란 대신 1..N의 값을 실제로 캡처하려면 몇 가지 옵션이 있습니다.

  1. 색인이 사용 가능한 경우 간단히 1 씩 증가시킬 수 있습니다 (예 🙂 ++i.
  2. 인덱스를 사용하지 않는 경우 (보다 효율적인 방법은) 배열을 만들지 만 N을 N + 1로 표시 한 다음 앞쪽으로 이동하는 것입니다.

    100 개의 숫자를 원한다면 :

    let arr; (arr=[ ...Array(101).keys() ]).shift()


답변

ES6에서는 다음을 수행 할 수 있습니다.

Array(N).fill().map((e,i)=>i+1);

http://jsbin.com/molabiluwa/edit?js,console

편집 : 변경 Array(45)Array(N)당신이 질문을 업데이 트했습니다 때문이다.

console.log(
  Array(45).fill(0).map((e,i)=>i+1)
);


답변

매우 인기있는 Underscore _.range 메소드를 사용하십시오.

// _.range([start], stop, [step])

_.range(10); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11); // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5); // => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1); //  => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0); // => []