同じ要素を複数回繰り返して配列を作成する


323

Pythonでは、[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;
}

反復ごとに配列を2倍にするため、反復回数が少ない非常に大きな配列を作成できます。


注:の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)だけを支払うことができます。一般に、可能な場合は追加することで配列の増加を回避することをお勧めします。最終的なサイズがわかっている場合は、それを使用してください。
トムKarzes 16

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

1
@noobninja:優れたソリューション。投票できるように、回答として再入力する必要があります。
jsalvata

693

ES6でArray fill()メソッドを使用

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

3
Internet ExplorerとOperaはまだサポートしていません。
DenisKolodin 2016年

4
Node.js <= 3はこれをサポートしていません。
Junle Li 2016

1
@DenisKolodin現在のOperaにはあります。そしてエッジも。互換表を
Janus Troelsen 2017

4
@MichaelでできますArray(5).fill([1,2,3]).flat()flat()はまだ非常に実験的なものであり、ブラウザのサポートは不十分であることに注意してください。
Niko Ruotsalainen

3
への引数fillは1回評価されるので、配列にArray(9).fill(someMutable)9つの参照を作成することに注意してくださいsomeMutable(1つを変更すると「すべて」が変更されます)。
カールスミス

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 2015

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プレコ

2
@blazkovicz Array(10)は、lenght = 10列挙可能なプロパティなしの配列を作成します。.map列挙可能なプロパティでのみ機能します。この.applyメソッドはこの配列を受け取り、それをarguments array(配列のようなオブジェクト)にマップして、Arrayコンストラクター関数に渡されます。引数の配列をスパースにすることはできないため、不足しているプロパティが設定されundefined、列挙可能になります。これで.map、意図したとおりに使用できます
CervEd

91

あなたが試すことができます:

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

アップデート(2018年1月6日)

これで、一連の文字を繰り返すことができます。

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

注:互換性とブラウザのサポートについては、fill(...)from(...)の詳細を確認してください。

アップデート(2019年5月11日)

fillまたはを使用せずにfrom、任意の長さの文字列に対して機能する別の方法:

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

上記の回答と同じです。完全性のために追加します。


1
いいね。最短かつシンプル。
Johann Echavarria 2014年

2
+1で簡単に処理できます。それから空の文字列の配列を作成できないのは残念です。それとは別に、非常に賢い...
2014年

1
Array(6).join( 'a')。split( 'a')は、空の文字列の配列を提供します。
Vivek 2014年

17
これは1文字の文字列に対してのみ機能するため、質問に完全には答えられません。
az_

3
@AlfonsoVergara:JavaScriptでは、Stringはプリミティブ(値セマンティック)型です。2つの文字列を取得して同じデータを参照する方法はありません(文字列 JavaScript では参照ではないため、値です)。文字列ではなく、オブジェクトとリストの参照セマンティクスに注意する必要があります。
Quuxplusone 2016

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 2014年

1
ドキュメントから:_.fill(Array(3)、2); これはES6からそれほど遠くない
2015年

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( '')の方が簡単ではないでしょうか?なぜ地図が必要なのですか?
アンジェラ

4
これは、[2、2、2、2、2]ではなく["2"、 "2"、 "2"、 "2"、 "2"]を返します。
ブルックホン

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配列の各インデックスに渡すと、同じオブジェクトを参照するため、1つを変更するとすべてが変更されることに注意してください。これが問題になったとしても、解決するのはそれほど難しくありません。
Shmiddty '19

多くのJavaScriptユーザーがネイティブ関数のプロトタイプを作成しないという要件に気付かない理由はわかりません。
brooNo 2015

2
fillメソッドは ES6に追加されました。そのため、プロトタイプに独自のものを追加することはお勧めしません。より高速でより機能的なバージョンを上書きすることになります。
Janus Troelsen 2015

1
@JanusTroelsen javascriptまたはサードパーティのライブラリの上書きを避けるために、宣言する前に存在するかどうかを確認できます。if (!Array.prototype.fill) { }
Oliver

1
@JanusTroelsen「実際のポリフィル」とはどういう意味ですか?ポリファイルを使った。つまり、機能の検出と実装がないかどうかを確認します。
Oliver



4

簡単な方法はありません。ループを作成して要素を配列にプッシュする必要があります。


ありがとう!受け入れる前に、効率の点で良いですか、pushそれともconcat良いですか?
Curious2learn 2012

CONCATは2つの配列を検査する必要があります。PUSHは別の要素を追加するだけなので、PUSHの方が一般的に効率的であると期待しますが、IDENTICAL DATAについては、Guffaの答えはそれを否定していると思います。
Diodeus-James MacFarlane 2012年

ループは必要ありません。私の答えをご覧ください。
Janus Troelsen 2013年

@JanusTroelsen、このアクションを実行する効率的な方法が必要でない限り、ループする必要はありません。あなたのものはあなたが見つけることができる遅い実装の1つです。[]へのpush()が最も高速です。
クリリス2015年

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" ]

既存のアレイを使用した素晴らしいワンライナー、私が必要とするもの。
ジェネリック


1

この関数は、(値)が整数または整数の文字列である限り、各要素が(値)と等しい(長さ)要素の配列を作成します。10進数は切り捨てられます。10進数が必要な場合は、"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
ドレンミ2015

1

ループを使用せずに2Dアレイを作成しようとしたときに、今日これを発見しました。振り返ってみると、新しいアレイに参加するのは簡単です。新しい配列をマッピングしようとしましたが、マップが空のスロットをスキップするため機能しません。

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

「#」文字は、任意の有効な単一文字にすることができます。5は、必要な要素の数の変数になります。7は、配列に入力する値です。

新しいfillメソッドの方が優れています。これをコーディングしたとき、それが存在することも知らなかったし、繰り返しがes6であることも知りませんでした。私は、reduceと組み合わせてこのトリックを使用してクールなことを行うことについてブログ投稿を作成します。

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つの名前があり、それらを1週間で繰り返したいとします。

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.