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


1161

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

var foo = [];

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

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


224
이 전체 페이지를 읽은 후에는 간단한 for-loop가 가장 단순하고 읽기 쉽고 오류가 적다는 결론을 얻었습니다.
Kokodoko

누구든지 고급 기능이 필요한 경우 숫자, 문자, 음수 / 양수 등 github.com/jonschlinkert/fill-range에 대해 node.js 라이브러리를 만들었습니다 . 그것은 괄호 확장을 위해 github.com/jonschlinkert/braces 에서, 글로브 패턴을 위해 github.com/jonschlinkert/micromatch 에서 사용됩니다
jonschlinkert

1
"... 1 ... N 포함"대신 "길이 N의 배열을 만드는 방법"이라고 편집해야합니다. 후자는 1에서 N까지의 값을 가진 요소가 있음을 의미합니다.
Steven Landow

7
@StevenLandow OP의 이름을 바꾸어야하는 이유는 무엇입니까? 그는 값을 가진 배열을 1 ... N원합니까?
Andre Elrico

좋은 질문, 좋은 제목, (kinda) 바보 같은 대답.
Bitterblue

답변:


381

내가 당신이 무엇을 얻는다면, 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/ 에서 실제로 확인하십시오.


4
당신이 내가 할 수있는 것보다 더 나은 내 질문을 표현하는 데 감명을 받았고, 당신이 실제로 필요한 것은 나중에 반복 할 수있는 숫자의 배열입니다.
Godders

147
@Godders : 이것이 당신이 찾고있는 것이라면 왜 배열이 필요합니까? 간단 var n = 45;하고 반복하는 1..n것이 좋습니다.
casablanca

3
@Godders-참고로, 배열을 길이 M으로 만든 후 크기를 줄이려면 간단히 foo.length = M--- 를 사용하십시오 . 잘린 정보는 손실됩니다. 액션 ==> 참조 jsfiddle.net/ACMXp
Peter Ajtai 2

24
나는 왜이 답변이 공감대를 가지고 있는지 알지 못합니다. 특히 OP 자신이 동의 할 때 위의 몇 가지 의견에는 아무런 의미가 없습니다 var n = 45;.
plalx

72
@ scunliffe : new Array(45);"45 요소 배열을 만들지"않습니다 (같은 의미로 [undefined,undefined,..undefined]). 오히려 "길이 = 45 인 빈 배열을 만듭니다"( [undefined x 45])와 동일합니다 var foo = []; foo.length=45;. 그 이유 forEach, 그리고 map이 경우에는 적용되지 않습니다.
tomalec

1307

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]

74
참고로, 이것은 항상 0 에서 시작합니다. 1에서 시작 map하도록 값 ( [...Array(10).keys()].map(x => x++);)을 조정하려면 배열에 a를 연결해야합니다.
Sterling Archer

32
값이 반환 된 후 우선 순위 증가 map(x => x++)map(x => ++x)인해 변경 됩니다. :)
Brock

92
어 뭐!? 왜 map간단하게 할 수 slice있습니까? [...Array(N+1).keys()].slice(1)
Robin

19
또는 사용하지 않고 keys1 개의지도 만 사용 ->Array.from(Array(10)).map((e,i)=>i+1)
yonatanmn

60
또는 키를 사용하여지도 및 단지에 매핑 함수를 통과하지 않습니다from Array.from(Array(10), (e,i)=>i+1)
파비오 ANTUNES

844

그렇게 할 수 있습니다 :

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 이전 브라우저 에서는 작동하지 않습니다 .


62
영리 +1하지만 느린 루프 원시적 이상 크기의 주문이다 참고 : jsperf.com/array-magic-vs-for
warpech

7
매우 영리합니다. 아마도 너무 그렇습니다. Function.prototype.call첫 번째 매개 변수가 반복자 매개 변수를 this통해 직접 매핑 하는 객체 라는 사실을 악용하면 Array.prototype.map특정 광채가 있습니다.
Noah Freitas

14
이것은 정말, 정말 영리합니다 (JS 남용에 대한 경계). 여기에서 가장 중요한 통찰력은 map할당되지 않은 가치에 대한 특질입니다 . 또 다른 버전은 (그리고 아마도 조금 더 명확하지만, 더 길지만) : Array.apply(null, { length: N }).map(function(element, index) { return index; })
Ben Reich

6
@BenReich 더 나은 (JS 남용 수준으로) : Array.apply(null, new Array(N)).map(function(_,i) { return i; }) 또는 es6 및 화살표 기능의 경우 더 짧습니다 : Array.apply(null, new Array(N)).map((_,i) => i)
oddy

1
이 일에서 시작, 그것은 실제로 OP의 질문에 대답 것이라고 배열을 반환하는 경우
하이 판

482

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)



5
0에서 시작하는 배열에 k ++ 사용
Borgboy

1
증분하려면 k++을 사용 하지 말고을 사용하십시오 ++k.
Alex

4
Poly-filling하지 않으면 IE에서 Beware Array.from이 지원되지 않습니다.
Lauren

2
TS 컴파일러가 만족스럽게 만들려면 사용하지 않는 매개 변수를 lodash로 바꾸는 것이 좋습니다. Array.from ({length : 5}, (_, k) => k + 1);
Journeycorner

296

배열은 본질적으로 길이를 관리합니다. 순회하면 인덱스를 메모리에 보관하고 해당 시점에서 참조 할 수 있습니다. 임의의 인덱스를 알아야 할 경우이 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()





수신 측에서 처리 할 수없는 데이터에 숫자 배열을 사용하는 경우 이것이 유용하다고 생각합니다. (값을 바꾸는 HTML 템플릿처럼)
Neil Monroe

누군가이 작업을 수행하는 이유는 드롭 다운 목록을 채우는 숫자 배열을 사용하여 사용자에게 1에서 10 사이의 선택권을 부여하는 것입니다. [1,2,3 ... 10] 작은 배열은 이해가되지만 1에서 50까지입니까? 종료 번호가 변경되면 어떻게됩니까?
CigarDoug

@ CigarDoug 유스 케이스가 의심의 여지가 없지만 내 추측은 작습니다. 숫자 배열이 필요한 이유는 무엇입니까? 일반적으로 배열을 반복 할 때 색인은 루프 본문 함수 (반복 본문 함수의 인수 또는 카운터 변수)의 일부로 사용되므로 숫자 배열을 유지하는 것이 사소한 것처럼 보입니다. 지정된 너비의 배열 또는 배열의 상한을 보유하는 변수를 만드는 것입니다. 몇 가지 사용 사례를 생각할 수 있지만 OP에 의해 표현 된 사례는 없었습니다.
vol7ron

4
내가 말했듯이, 1에서 10까지의 숫자로 드롭 다운을 채워야합니다. 그게 전부입니다. 유스 케이스가 있습니다. 내 유스 케이스입니다. 이것이 내가이 페이지를 찾은 방법입니다. 따라서 손으로 배열을 만드는 것은 내가 본 것보다 덜 복잡합니다. 내 요구 사항은 OP의 요구 사항이 아닙니다. 그러나 나는 대답이있다.
CigarDoug

1
@ vol7ron 유스 케이스가 있으며 나도 있습니다. 페이징에서 각도로 클릭 할 수있는 바닥 글의 페이지를 표시하고 싶습니다. 따라서 * ngFor = "let p of pagesCounter"를 사용하여 뷰의 요소를 반복합니다. 더 나은 해결책이 있습니까? BTW, stackoverflow.com/questions/36354325/…를
Dalibor

186

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)
);


3
하나는 전체이기 때문에 O 더 불쾌한 이상의 .join.split버전 -하지만 난 여전히 겸손 루프가 더 나은 생각합니다.
Robin

@Robin에 동의합니다-알고리즘 복잡성을 제외하고 겸손한 루프는 항상 더 읽기 쉽습니다. 그러나 Java에서 람다가 등장함에 따라 map곧 이와 같은 표준이 될 것이라고 생각 합니다.
Nate

4
const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
Robin

8
.fill()필요한지 모르겠습니다 . 노드의 repl을 테스트 할 때이지만, 이후 Array(1)[0] === undefinedfill () 호출에 어떤 차이가 Array(1).fill(undefined)있습니까?
Dominic

11
관심있는 다른 사람들을 위해 Array (N)과 Array (N) .fill ()의 차이점은 여기에
Dominic

108

매우 인기있는 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); // => []


대박. 어쨌든 밑줄을 사용하지 않는 큰 프로젝트를 보여주세요 ...
Erez Cohen

63
function range(start, end) {
    var foo = [];
    for (var i = start; i <= end; i++) {
        foo.push(i);
    }
    return foo;
}

그런 다음

var foo = range(1, 5);

Javascript에는 기본 제공 방법이 없지만 두 번 이상 수행해야 할 경우 완벽하게 유효한 유틸리티 함수입니다.

편집 : 내 생각에 다음은 더 나은 범위 기능입니다. 아마 LINQ에 의해 편향되어 있기 때문에 더 많은 경우에 더 유용하다고 생각합니다. 귀하의 마일리지가 다를 수 있습니다.

function range(start, count) {
    if(arguments.length == 1) {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++) {
        foo.push(start + i);
    }
    return foo;
}

2
나는 이것을 좋아한다. 추가 마일을 사용하려면 Array.prototype.range = function (start, end) {...};로 선언하면됩니다. 그런 다음 모든 Array 객체에서 range (x, y)를 호출 할 수 있습니다.
Zach Rattner

8
오히려 모든 배열 에이 메소드를 가질 이유가 없기 때문에 Array대신 메소드로 만드십시오 Array.prototype.
adamse

9
Array.range(1, 5)아마도 더 적절할 것입니다. 그러나 글쓰기에는 멋진 것이 [].range(1, 5)있습니다.
MooGoo

"대신 Array.prototype 대신 Array의 메소드로 만드십시오"-차이점은 무엇입니까? 특정 배열에서만 의미합니까?
pilau

3
@pilau adamse가 말했듯이 이상하게 보입니다. 프로토 타입에 있다면 말할 수 있습니다 foo = [1, 2, 3]; bar = foo.range(0, 10);. 그러나 그것은 단지 혼란 스럽습니다. bar = Array.range(0, 10)훨씬 더 명확하고 명시 적입니다. 범위는 인스턴스와 관련이 없으므로 인스턴스 메소드로 만들 이유가 없습니다.
Ian Henry

53

Arrayv8 을 채우는 가장 빠른 방법 은 다음과 같습니다.

[...Array(5)].map((_,i) => i);

결과는 다음과 같습니다. [0, 1, 2, 3, 4]


여분의 변수없이 그것을 할 수있는 방법이
있습니까?

@bluejayke no :(
lexy dykyі

가혹합니다. .map의 소스 코드가 무엇인지 아십니까? 나는 그것이 for 루프보다 빠른지 확실하지 않지만 이론적으로 우리는 단지 property를 정의하고 새로운 것을 만들 수있다
bluejayke

49

이 질문에는 많은 복잡한 답변이 있지만 간단한 한 줄짜리가 있습니다.

[...Array(255).keys()].map(x => x + 1)

또한 위의 내용을 작성하는 것이 짧고 깔끔하지만 다음은 약간 더 빠릅니다 (최대 길이).

127, Int8,

255, Uint8,

32,767, Int16,

65,535, Uint16,

2,147,483,647, Int32,

4,294,967,295, Uint32.

( max integer values 기준) 또한 Typed Arrays 에 대한 자세한 내용입니다 .

(new Uint8Array(255)).map(($,i) => i + 1);

이 솔루션은 두 개의 배열을 만들고 추가 변수 선언 "$"을 사용하므로이 방법도 그리 이상적이지는 않습니다 (이 방법을 사용하여 해결할 방법은 확실하지 않습니다). 다음 솔루션이 가능한 가장 빠른 방법이라고 생각합니다.

for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;

이 문장을 작성한 후 언제든지 현재 범위에서 변수 "arr"을 간단하게 사용할 수 있습니다.

간단한 기능을 만들고 싶다면 (기본 검증을 통해) :

function range(min, max) {
    min = min && min.constructor == Number ? min : 0;
    !(max && max.constructor == Number && max > min) && // boolean statements can also be used with void return types, like a one-line if statement.
        ((max = min) & (min = 0));  //if there is a "max" argument specified, then first check if its a number and if its graeter than min: if so, stay the same; if not, then consider it as if there is no "max" in the first place, and "max" becomes "min" (and min becomes 0 by default)

    for(var i = 0, arr = new (
        max < 128 ? Int8Array : 
        max < 256 ? Uint8Array :
        max < 32768 ? Int16Array : 
        max < 65536 ? Uint16Array :
        max < 2147483648 ? Int32Array :
        max < 4294967296 ? Uint32Array : 
        Array
    )(max - min); i < arr.length; i++) arr[i] = i + min;
    return arr;
}



//and you can loop through it easily using array methods if you want
range(1,11).forEach(x => console.log(x));

//or if you're used to pythons `for...in` you can do a similar thing with `for...of` if you want the individual values:
for(i of range(2020,2025)) console.log(i);

//or if you really want to use `for..in`, you can, but then you will only be accessing the keys:

for(k in range(25,30)) console.log(k);

console.log(
    range(1,128).constructor.name,
    range(200).constructor.name,
    range(400,900).constructor.name,
    range(33333).constructor.name,
    range(823, 100000).constructor.name,
    range(10,4) // when the "min" argument is greater than the "max", then it just considers it as if there is no "max", and the new max becomes "min", and "min" becomes 0, as if "max" was never even written
);


따라서 위의 기능을 사용하면 위의 초 저속 "단일 원 라이너"가 초고속, 심지어 더 짧아집니다.

range(1,14000);

@JVG이지만 더 빠른 기능은 아닙니다.
bluejayke

정확히 맞습니다. 모두가 찾고있는이 간단한 라이너입니다!
supersan

@supersan 비록 슈퍼 느린 :)
bluejayke

새로운 fill방법으로 현대 자바 스크립트 :Array(255).fill(0,0,255)
cacoder

@cacoder 얼마나 빠르며, 얼마나 많은 배열을 만들고 얼마나 많은 반복을합니까?
bluejayke 2016 년

42

이것을 사용할 수 있습니다 :

new Array(/*any number which you want*/)
    .join().split(',')
    .map(function(item, index){ return ++index;})

예를 들어

new Array(10)
    .join().split(',')
    .map(function(item, index){ return ++index;})

다음 배열을 만듭니다.

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

또한 왜 안 new Array(10).join().split(',').map(function() {return ++arguments[1]});됩니까?
super

1
일부 경우 @Murplyx는 인수가있는 함수가 JS 엔진에 의해 최적화되지 않습니다 (V8의 경우에도 true, jsperf.com/arguments-vs-array-argument/2 참조 )
nktssh

4
이것은 흥미로운 해결책이지만 전적으로 비현실적입니다-배열을 3 번 파싱해야합니다 (한 번 join, 한 번 split, 실제로 원하는 것을 한 번)하는 것은 좋지 않습니다-나는 그들이 호의에서 벗어난 것으로 알고 있습니다 어떤 이유로 든, 그러나 단순히 좋은 구식 루프 를 사용하는 것이 훨씬 좋습니다 !
Robin

42

ES6이 트릭을 수행합니다.

[...Array(12).keys()]

결과를 확인하십시오.

[...Array(12).keys()].map(number => console.log(number))


5
실제로, 그들은 0..N-1이 아닌 1..N을 요청했습니다
YakovL

1
네. [...Array(N + 1).keys()].slice(1)1.N
David G

어떤 이유로이 솔루션은 Expo (반응 형) 앱의 프로덕션 버전에서 작동하지 않습니다. [...Array(N + 1).keys()]이 코드는 빈 배열을 반환하지만 개발 모드를 사용하여 프로덕션 모드에서만 작동합니다.
FabianoLothor

3
.keys()해답은 이미 몇 년 전에 주어졌으며 500 개 이상의 공감대가 있습니다. 당신의 대답은 무엇에 추가됩니까?
Dan Dascalescu

39

내가 앱에서 d3.js 를 사용하는 경우 D3는이를 위해 돕는 도우미 기능을 제공합니다.

따라서 0에서 4까지의 배열을 얻으려면 다음과 같이 쉽습니다.

d3.range(5)
[0, 1, 2, 3, 4]

요청 한대로 1에서 5까지 배열을 가져옵니다.

d3.range(1, 5+1)
[1, 2, 3, 4, 5]

자세한 내용은 이 튜토리얼 을 확인하십시오 .


이 의견은 RamdaJS에서 range () 함수 를 찾는 아이디어를주었습니다 . 현재 프로젝트에서 작업중 인 JS 라이브러리입니다. 완전한.
morphatic


38

이것은 아마도 숫자 배열을 생성하는 가장 빠른 방법 일 것입니다.

최단

var a=[],b=N;while(b--)a[b]=b+1;

인라인

var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]

1부터 시작하려면

var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]

기능을 원하십니까?

function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]

왜?

  1. while 가장 빠른 루프입니다

  2. 직접 설정이보다 빠릅니다. push

  3. [] 보다 빠르다 new Array(10)

  4. 짧습니다 ... 첫 번째 코드를보십시오. 여기에있는 다른 모든 기능을 살펴보십시오.

당신이 좋아하는 경우없이 살 수 없다 에 대한

for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]

또는

for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]

8
이러한 클레임을 벤치 마크로 백업하는 것이 좋습니다. jsperf.com을 사용해보십시오 .
매트 볼

2
lol jsperf ... pls Matt 그냥 내 대답이 내 다른 사람들을 다운 다운하는 것을 멈추지 않기 때문에 ... stackoverflow.com/a/18344296/2450730 ... console.time () 사용 또는 어떻게 호출되는지 ... NOT jsperf .
cocco

4
참고 : John Reisig가 몇 년 전에 처음으로 게시 한 것처럼 일부 플랫폼 (Windows : P를 의미)에서 16ms마다 한 번씩 브라우저에 시간이 공급되고 있습니다. 또한 멀티 태스킹 환경에서 실행 시간을 측정하는 데 다른 문제가 있습니다. jsperf.com은 통계적으로 정확하도록 테스트 실행을 구현했습니다. 그것은 실행해도 괜찮은지 console.time()직관을 얻을 수 있지만, 증거를 들어, jsperf.com이 필요하고 그것은 당신이 다른 사람의 결과 (다른 하드웨어 등) 브라우저 교차 보여줍니다
naugtur

3
@cocco 이것은 잘못되었습니다 :var a=[],b=N;while(b--){a[b]=a+1};
vintagexav

5
@ cocco- 동안은 아니다 항상 다른 루프보다 더 빨리. 일부 브라우저에서는 감소하는 while 루프가 for 루프보다 속도가 훨씬 느리므로 최적화가 너무 많은 구현이 많기 때문에 Javascript 성능에 대한 일반적인 설명을 할 수 없습니다. 그러나 일반적으로 나는 당신의 접근 방식을 좋아합니다. ;-)
RobG

32

채우는 새로운 방법 Array은 다음과 같습니다.

const array = [...Array(5).keys()]
console.log(array)

결과는 다음과 같습니다. [0, 1, 2, 3, 4]


tecnically 질문이 0- (N-1)가 아닌 1-N에서 왔지만이 sa에 대한 좋은 대답
bluejayke

31

lodash를 사용하는 경우 _.range 를 사용할 수 있습니다 .

_.range([start=0], end, [step=1])

처음부터 끝까지 (포함하지 않음) 진행하는 숫자 배열 (양수 및 / 또는 음수)을 만듭니다. 음수 시작이 종료 또는 단계없이 지정된 경우 -1 단계가 사용됩니다. end를 지정하지 않으면 start로 시작하여 0으로 설정됩니다.

예 :

_.range(4);
// ➜ [0, 1, 2, 3]

_.range(-4);
// ➜ [0, -1, -2, -3]

_.range(1, 5);
// ➜ [1, 2, 3, 4]

_.range(0, 20, 5);
// ➜ [0, 5, 10, 15]

_.range(0, -4, -1);
// ➜ [0, -1, -2, -3]

_.range(1, 4, 0);
// ➜ [1, 1, 1]

_.range(0);
// ➜ []

30

ES6을 사용하면 다음을 수행 할 수 있습니다.

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

배열의 값은 실제로이 솔루션을 사용하여 작성되며, 이후 mapforEach작동합니다.
dontmentionthebackup 8

27

최종 요약 보고서 .. Drrruummm Rolll-

이것은 인 짧은 코드 사이즈 N (여기서는 10)의 배열을 생성하기 ES6 사용없이 . 위의 Cocco 버전은 가깝지만 가장 짧지는 않습니다.

(function(n){for(a=[];n--;a[n]=n+1);return a})(10)

그러나이 코드 골프 의 확실한 승자 는 (최소 바이트의 소스 코드에서 특정 문제를 해결하기위한 경쟁) Niko Ruotsalainen 입니다. 배열 생성자와 ES6 스프레드 연산자 사용 . (대부분의 ES6 구문은 유효한 typeScript이지만 다음은 아닙니다. 사용하는 동안 신중해야합니다.)

[...Array(10).keys()]

왜 다운 투표? 긴 답변 목록을 따르기가 어렵 기 때문에 요약을 생각했습니다.
sapy

이 0-10 아닌가? [... Array (10) .keys ()]
Greg

Webstorm은 (new Array (10)). keys ()를 제안합니다. 맞습니까?
Guy

(new Array (10)). keys ()는 배열이 아닌 ArrayIterator {}을 반환합니다
sapy

이것은 전역 변수를 만듭니다 a. 루프는for(var a=[];n--;a[n]=n+1)
kube

20

ES6 에는 2 개의 인수 를 받는 Array.from 을 사용하는 또 다른 방법이 있습니다 . 첫 번째는 arrayLike (이 경우 length속성 이있는 객체 )이고 두 번째는 매핑 함수입니다 (이 경우에는 항목을 인덱스에 매핑합니다)

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

이것은 더 짧고 짝수를 생성하는 것과 같은 다른 시퀀스에 사용할 수 있습니다

Array.from({length:10}, (v,i) => i*2)

또한 이것은 어레이를 통해 한 번만 반복되므로 대부분의 다른 방법보다 성능이 좋습니다. 스 니핏에서 일부 비교를 확인하십시오.

// open the dev console to see results

count = 100000

console.time("from object")
for (let i = 0; i<count; i++) {
  range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")

console.time("from keys")
for (let i =0; i<count; i++) {
  range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")

console.time("apply")
for (let i = 0; i<count; i++) {
  range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")


이봐, 깔끔해 난 좋아 그러나 OP가 기대하는 결과를 반환하지는 않습니다. 그렇게하려면 다음과 같이 작성해야합니다.Array.from({length:N}, (v,i) => i+1)
CervEd


16

=>ES6 표준의 새로운 Array 메소드 및 함수 구문 사용 (작성 당시 Firefox 만 해당)

구멍을 채워서 undefined:

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

Array.from회전 "구멍"에 undefined너무 Array.map예상대로 작동합니다 :

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

7
마찬가지로 ES6에서도 다음을 수행 할 수 있습니다 Array.from({length: N}, (v, k) => k).
XåpplI'-I0llwlg'I-

Xappli의 접근 방식이 선호됩니다. Array.from은 거의이 정확한 시나리오를 위해 만들어졌으며 매핑 콜백을 의미합니다. Array.prototype.map.call예를 들어 NodeLists에서 반환되는 것과 같은 장황한 접근 방식을 사용하지 않고 배열과 같은 배열에서 Array 메서드를 사용하려는 일반적인 문제에 대한 훌륭한 솔루션 입니다 document.querySelectorAll. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Josh at Qaribou

나는 이것을 밑줄 범위 구문과 비교하고 있으며 범위는 더 잘 읽습니다.
ooolala 5

기술적 Array.from으로 희소 값이 정의되지 않은 것은 아닙니다 . 오히려 Array(5)희소 값을 정의되지 않은 값으로 해석하는 arguments 객체라고합니다. :
CervEd



12

ES6에서 :

Array.from({length: 1000}, (_, i) => i);

ES5 :

Array.apply(0, {length: 1000}).map(function(x,i){return i});

10

또 다른 ES6 버전.

Array.from두 번째 선택적 인수 를 사용하여 :

Array.from (arrayLike [, mapFn [, thisArg]])

Array(10)위치 에서 번호가 매겨진 배열을 만들 수 있습니다 .

Array.from(Array(10), (_, i) => i)

var arr = Array.from(Array(10), (_, i) => i);
document.write(arr);


이것은보다 복잡하고 ~ 10 배 느립니다 [...Array(11).keys()].slice(1).
Dan Dascalescu

10

현재이 완전한 답변 목록에없는 유일한 맛은 발전기를 갖춘 것이다. 이를 해결하기 위해 :

const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]

다음과 같이 사용할 수 있습니다.

gen(4) // [0,1,2,3]

이것에 대한 좋은 점은 증가시킬 필요가 없다는 것입니다 ... @ igor-shubin의 대답에서 영감을 얻으려면 매우 쉬운 무작위 배열을 만들 수 있습니다.

const gen = N => [...(function*(){let i=0;
  while(i++<N) yield Math.random()
})()]

그리고 운영 비용이 오래 걸리는 것보다는 다음 과 같습니다.

const slow = N => new Array(N).join().split(',').map((e,i)=>i*5)
// [0,5,10,15,...]

대신 할 수 있습니다 :

const fast = N => [...(function*(){let i=0;while(i++<N)yield i*5})()]

10

Es6에서 배열 채우기 및 맵을 사용할 수 있습니다. 이 질문에 대한 답변에서 일부 사람들이 제안한 것처럼. 다음은 몇 가지 예입니다.

Example-One: Array(10).fill(0).map((e,i)=>i+1)

Result-One: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Example-Two: Array(100/10).fill(0).map((e,i)=>(i*10)+10)

Result-Two:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

나는 이것을 똑바로 쉽게 찾을 수 있기 때문에 이것을 선호합니다.



9

ES6 사용

const generateArray = n => [...Array(n)].map((_, index) => index + 1);

감사! 이것은 내 의견으로는 가장 우아한 답변이었습니다! Array.from(Array(n))스프레드 연산자가 지원되지 않는 경우 에도 사용할 수 있습니다 .
Amit

처음에는 왜 스프레드 연산자를 사용해야하는지 몰랐지만 mapMDN 에 대해 다음과 같은 내용 읽었습니다 . "배열의 누락 된 요소 (즉, 설정되지 않은 인덱스, 삭제되었거나 값이 할당 된 적이 없습니다. ")
battmanz

9

Object.keys(Array.apply(0, Array(3))).map(Number)

를 반환 [0, 1, 2]합니다. Igor Shubin의 탁월한 답변 과 매우 유사 하지만 약간 덜 까다 롭고 한 문자 더 길었습니다.

설명:

  • Array(3) // [undefined × 3]길이 n = 3의 배열을 생성하십시오. 불행히도이 배열은 우리에게 거의 쓸모가 없으므로 우리는 ...
  • Array.apply(0,Array(3)) // [undefined, undefined, undefined]배열을 반복 가능하게 만듭니다. 참고 : null은 apply의 첫 번째 인수보다 일반적이지만 0은 짧습니다.
  • Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2'] 그런 다음 배열의 키를 가져옵니다 (배열은 typeof 배열이기 때문에 키에 대한 인덱스가있는 객체이기 때문에 작동합니다.
  • Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2] 문자열을 숫자로 변환하여 키 위에 매핑하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.