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 씩 증가시킬 수 있습니다 (예 🙂
++i
. -
인덱스를 사용하지 않는 경우 (보다 효율적인 방법은) 배열을 만들지 만 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); // => []