동일한 요소가 여러 번 반복되는 배열 만들기


323

파이썬에서 [2]리스트가있는 곳 에서 다음 코드는이 출력을 제공합니다.

[2] * 5 # Outputs: [2,2,2,2,2]

JavaScript의 배열로 이것을 수행하는 쉬운 방법이 있습니까?

나는 그것을하기 위해 다음 함수를 작성했지만 더 짧거나 더 좋은 것이 있습니까?

var repeatelem = function(elem, n){
    // returns an array with element elem repeated n times.
    var arr = [];

    for (var i = 0; i <= n; i++) {
        arr = arr.concat(elem);
    };

    return arr;
};


답변:


52

다음과 같이 할 수 있습니다 :

function fillArray(value, len) {
  if (len == 0) return [];
  var a = [value];
  while (a.length * 2 <= len) a = a.concat(a);
  if (a.length < len) a = a.concat(a.slice(0, len - a.length));
  return a;
}

각 반복마다 배열을 두 배로 늘리므로 반복 횟수가 거의없는 매우 큰 배열을 만들 수 있습니다.


참고 : 반복 할 때마다 새 배열을 만들 므로 push대신 대신을 사용하여 함수를 크게 향상시킬 수 있습니다 . 이와 같이 (배열로 작업하는 방법의 예와 같이) :concatconcat

function fillArray(value, len) {
  var arr = [];
  for (var i = 0; i < len; i++) {
    arr.push(value);
  }
  return arr;
}

11
을 사용하여 모든 항목 arr = new Array(len);을 미리 할당 한 다음 루프에서 색인별로 할당하는 것이 훨씬 효율적 arr[i] = value;입니다. 그렇게하면 배열이 커질 때 계속 재할 당하지 않고 O (n) 만 지불하면됩니다. 일반적으로 가능하면 추가하여 배열이 커지는 것을 피하는 것이 좋습니다. 최종 크기를 알고 있으면 사용하십시오.
— Tom Karzes

26
Array.from({length:5}).map(x => 2)
— noobninja

1
@ noobninja : 훌륭한 솔루션; 답변으로 다시 입력하여 공감할 수 있습니다.
— jsalvata

692

ES6에서 Array fill () 메소드 사용

Array(5).fill(2)
//=> [2, 2, 2, 2, 2]

3
Internet Explorer와 Opera는 아직 지원하지 않습니다.
— DenisKolodin 2016 년

4
Node.js <= 3은 이것을 지원하지 않습니다.
— Junle Li

1
@DenisKolodin 현재 오페라는 않습니다. 그리고 가장자리도. 참조 의 compat 테이블
— 야누스 Troelsen

4
@Michael 당신은 그것을 할 수 있습니다 Array(5).fill([1,2,3]).flat(). 그 주 ) (평면을 여전히 실험하고 브라우저 지원이 좋지 않습니다.
— Niko Ruotsalainen

3
인수 fill는 한 번 평가되므로 배열에서 Array(9).fill(someMutable)9 개의 참조를 만듭니다 someMutable(하나를 변경하면 '모두'가 변경됨).
— Carl Smith

146
>>> Array.apply(null, Array(10)).map(function(){return 5})
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
>>> //Or in ES6
>>> [...Array(10)].map((_, i) => 5)
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]

6
바보 같은 질문이지만 왜 새 Array (10) .map이 작동하지 않습니까?
— blazkovicz

1
blazkovicz, 이유에 대한 이 답변에 대한 zertosh의 의견을 참조하십시오 .
— 로스 로저스

5
ES6을 Array(...Array(10)).map(() => 5)사용하면 스프레드 연산자를 사용하거나 다음으로 업그레이드 할 수 있습니다.Array.from(Array(10)).map(() => 5)
— Christophe Vidal

4
MDN 에 따르면 다음과 같이 할 수 있습니다.Array.from({length: 10}, () => 5);
— Plusb Preco

2
@blazkovicz Array (10)은 lenght = 10열거 가능한 속성 이 없는 배열을 만듭니다 . .map열거 가능한 속성에서만 작동합니다. 이 .apply메소드는이 배열을 가져 와서 arguments array배열과 같은 오브젝트 로 맵핑 하여 Array생성자 함수에 전달 합니다. arguments 배열은 희박 할 수 없으므로 누락 된 속성이 설정 undefined되고 열거 가능해 집니다. 이제 .map의도 한대로 사용할 수 있습니다
— CervEd

91

당신은 시도 할 수 있습니다:

Array(6).join('a').split(''); // returns ['a','a','a','a','a'] (5 times)

업데이트 (01/06/2018) :

이제 일련의 문자를 반복 할 수 있습니다.

new Array(5).fill('a'); // give the same result as above;
// or
Array.from({ length: 5 }).fill('a')

참고 : 호환성 및 브라우저 지원에 대해서는 fill (...) 및 from (...) 에 대해 자세히 확인하십시오 .

업데이트 (05/11/2019) :

또 다른 방법, 사용하지 않고 fill또는 from어떤 길이의 문자열에 대한 그 작품을 :

Array.apply(null, Array(3)).map(_ => 'abc') // ['abc', 'abc', 'abc']

위의 답변 과 동일합니다 . 완전성을 위해 추가.


1
좋은. 가장 짧고 간단합니다.
— Johann Echavarria

2
간단한 취급을 위해 +1 빈 문자열 배열을 만들 수 없다는 수치입니다. 똑똑한 것
— 말고

1
Array (6) .join ( 'a'). split ( 'a')은 빈 문자열 배열을 제공합니다.
— Vivek

17
이것은 1 개의 문자열에서만 작동하므로 질문에 완전히 대답하지는 않습니다.
— az_

3
@AlfonsoVergara : Javascript에서 String은 기본 (값 시맨틱) 유형입니다. 동일한 데이터를 참조하기 위해 두 개의 문자열을 얻을 수있는 방법 은 없습니다 (문자열 은 Javascript에서 참조 되지 않기 때문에 값입니다). 문자열이 아닌 객체와 목록을 가진 참조 의미론을 조심해야합니다.
— Quuxplusone

36

Array.from({length:5}, i => 1) // [1, 1, 1, 1, 1]

또는 가치가 증가하는 배열을 만듭니다

Array.from({length:5}, (e, i)=>i) // [0, 1, 2, 3, 4]


다이나믹 한 요소가 필요한 경우에 가장 좋은 방법입니다.
— IliasT

Array.from({length:5}, i => 1)=> i는 undefined빈 값을 나타 내기 때문입니다. Array.from({length:5}, (e, i)=>i)=> e는 undefined빈 값을 나타 내기 때문입니다. 그것은해야 Array.from({length:5}, v => 1)하고Array.from({length:5}, (v, i)=>i)
— 라팔 Enden

33

lodash 에서는 그렇게 나쁘지 않습니다.

_.flatten(_.times(5, function () { return [2]; }));
// [2, 2, 2, 2, 2]

편집 : 더 나은 :

_.times(5, _.constant(2));
// [2, 2, 2, 2, 2]

편집 : 더 나은 :

_.fill(Array(5), 2);

3
_.times (length, _.constant (value))
— user1533401

1
문서에서 : _.fill (Array (3), 2); ES6와 멀지 않은 곳
— kert

15

[c] * n 다음과 같이 쓸 수 있습니다 :

Array(n+1).join(1).split('').map(function(){return c;})

그래서 [2] * 5

Array(6).join(1).split('').map(function(){return 2;})

실제로 Array (6) .join (2) .split ( '')이 더 쉽지 않을까요? 왜지도가 필요할까요?
— Angela

4
[2, 2, 2, 2, 2] 대신 [ "2", "2", "2", "2", "2"]를 반환합니다.
— brook hong

10

Array의 기능을 다음과 같이 확장 할 수도 있습니다.

Array.prototype.fill = function(val){
    for (var i = 0; i < this.length; i++){
        this[i] = val;
    }
    return this;
};
// used like:
var arry = new Array(5)​.fill(2);
// or
var arry = new Array(5);
arry.fill(2);


​console.log(arry);​ //[2, 2, 2, 2, 2] 

내장 라이브러리의 기능을 확장하면 타사 라이브러리로 작업하는 경우 문제가 발생할 수 있습니다. 항상 결정에 무게를 두십시오.


fill배열의 각 인덱스에 객체를 전달 하면 동일한 객체를 참조하므로 하나를 변경하면 모든 객체가 변경됩니다. 이것이 문제가되면 해결하기가 어렵지 않습니다.
— Shmiddty

많은 자바 스크립트 사용자가 원시 함수를 프로토 타입하지 않아야하는 요구 사항을 모르는 이유를 모르겠습니다.
— brooNo

2
충전 방법 ES6 첨가되었다. 따라서 프로토 타입에 자신의 물건을 추가하는 것은 권장하지 않습니다. 더 빠르고 더 강력한 버전을 덮어 쓰게됩니다.
— 야누스 트롤 슨

1
@JanusTroelsen 자바 스크립트 또는 타사 라이브러리를 덮어 쓰지 않도록 선언하기 전에 존재하는지 확인할 수 있습니다. if (!Array.prototype.fill) { }
— Oliver

1
@JanusTroelsen "실제 폴리 필"이란 무엇입니까?. 나는 polifyll을 사용했습니다. 의미 : 기능 감지 및 구현이 아닌 경우 확인하십시오.
— Oliver



4

더 쉬운 방법은 없습니다. 루프를 만들고 요소를 배열로 밀어 넣어야합니다.


감사! 나는 동의하기 전에이며, push더 나은 또는 concat효율성의 관점에서 더 나은?
— Curious2learn

CONCAT은 두 개의 배열을 검사해야하며 PUSH는 다른 요소를 추가하기 때문에 PUSH가 일반적으로 더 효율적일 것으로 기대하지만 IDENTICAL DATA의 경우 Guffa의 대답이 그것을 생각합니다.
— Diodeus-James MacFarlane

루프가 필요하지 않습니다. 내 답변을 참조하십시오.
— Janus Troelsen

@JanusTroelsen,이 작업을 수행하는 효율적인 방법을 원하지 않는 한 반복 할 필요가 없습니다. 당신은 당신이 찾을 수있는 가장 느린 방해 중 하나입니다. push () to []가 가장 빠릅니다.
— chrilith

4

이 기능을 사용하십시오 :

function repeatElement(element, count) {
    return Array(count).fill(element)
}
>>> repeatElement('#', 5).join('')
"#####"

또는보다 컴팩트 한 버전의 경우 :

const repeatElement = (element, count) =>
    Array(count).fill(element)
>>> repeatElement('#', 5).join('')
"#####"

또는 카레 가능 버전의 경우 :

const repeatElement = element => count =>
    Array(count).fill(element)
>>> repeatElement('#')(5).join('')
"#####"

이 기능을 목록과 함께 사용할 수 있습니다.

const repeatElement = (element, count) =>
    Array(count).fill(element)

>>> ['a', 'b', ...repeatElement('c', 5)]
['a', 'b', 'c', 'c', 'c', 'c', 'c']

4

배열을 반복해야하는 경우 다음을 사용하십시오.

Array.from({ length: 3 }).fill(['a','b','c']).flat()

돌아올 것이다

Array(9) [ "a", "b", "c", "a", "b", "c", "a", "b", "c" ]

기존 어레이를 사용하는 훌륭한 oneliner, 내가 필요한 것.
— gneric

2

다른 하나의 라이너 :

Array.prototype.map.call([]+Array(5+1),function(){ return '2'; })

1

이 함수는 (값)이 정수 또는 정수 문자열 인 한 각 요소가 (값) 인 (길이) 요소의 배열을 만듭니다. 십진수는 잘립니다. 십진수를 원하면 "parseInt ( "를 " parseFloat ( "

function fillArray(length, intValue) {
     var vals = (new Array(length + 1)).join(intValue + '|').split('|').slice(0,length);
     for(var i = 0; i < length; i += 1) {
         vals[i] = parseInt(vals[i]);
     }
     return vals;
}

예 :

fillArray(5, 7) // returns [7,7,7,7,7]
fillArray(5, 7.5) // returns [7,7,7,7,7]
fillArray(5, 200) // returns [200,200,200,200,200]

1

배열을 사용할 때 언급 한 방법에 문제가 있습니다.

var array = ['foo', 'bar', 'foobar'];
var filled = array.fill(7);

//filled should be ['foo', 'bar', 'foobar', 'foo', 'bar', 'foobar', 'foo']

이것을 얻으려면 사용하고 있습니다 :

Array.prototype.fill = function(val){
    var l = this.length;
    if(l < val){
        for(var i = val-1-l; i >= 0; i--){
            this[i+l] = this[i % l];
        }
    }
    return this;
};

이것은 좋지만 아마도 이름을 지정해야합니다 cycle.
— Drenmi

1

루프를 사용하지 않고 2D 배열을 만들려고 오늘 이것을 발견했습니다. 돌이켜 보면 새 배열에 가입하는 것이 깔끔합니다. 맵이 빈 슬롯을 건너 뛸 때 작동하지 않는 새 배열을 매핑하려고했습니다.

"#".repeat(5).split('').map(x => 0)

"#"문자는 유효한 단일 문자 일 수 있습니다. 5는 원하는 요소 수에 대한 변수입니다. 7은 배열을 채우려는 값입니다.

새로운 채우기 방법이 더 좋으며, 이것을 코딩 할 때 그것이 존재하는지 알지 못했고 반복이 es6라는 것을 알지 못했습니다. 멋진 일을 줄이기 위해이 트릭을 사용하는 방법에 대한 블로그 게시물을 작성하려고합니다.

http://jburger.us.to/2016/07/14/functionally-create-a-2d-array/




0

lodash / underscore와 같은 utlity 벨트를 사용하는 경우 다음과 같이 할 수 있습니다 :)

let result = _.map(_.times(foo), function() {return bar})

0

단일 라이너로도 사용할 수 있습니다.

function repeat(arr, len) {
    while (arr.length < len) arr = arr.concat(arr.slice(0, len-arr.length));
    return arr;
}

0

Vivek의 답변을 개선 하면 길이 n의 배열을 채우기 위해 모든 길이의 문자열에 작동합니다.Array(n+1).join('[string to be repeated][separator]').split('[separator]').slice(0, n)


-1

배열 (n 항목)을 m 번 반복 / 반복하는 방법이 필요했습니다.

예를 들어 (사람의) 목록을 주 / 월에 배포합니다. 3 개의 이름이 있는데 일주일에 반복하고 싶다고 가정 해 봅시다.

fillArray(["Adam", "Blair", "Curtis"], 7); // returns ["Adam", "Blair", "Curtis", "Adam", "Blair", "Curtis", "Adam"]

function fillArray(pattern, count) {
    let result = [];
    if (["number", "string"].includes(typeof pattern)) {
        result = new Array(5);
        result.fill(pattern);
    }
    else if (pattern instanceof Array) {
        for (let i = 0; i < count; i++) {
            result = result.concat(pattern);
        }
        result = result.slice(0, count);
    }
    return result;
}

fillArray("a", 5);        // ["a", "a", "a", "a", "a"]
fillArray(1, 5);          // [1, 1, 1, 1, 1]
fillArray(["a", "b"], 5); // ["a", "b", "a", "b", "a"]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.