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


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)=> iundefined빈 값을 나타 내기 때문입니다. Array.from({length:5}, (e, i)=>i)=> eundefined빈 값을 나타 내기 때문입니다. 그것은해야 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.