【问题标题】:Create an array with same element repeated multiple times创建一个重复多次的相同元素的数组
【发布时间】:2012-09-12 06:14:12
【问题描述】:

在 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;
};

【问题讨论】:

标签: javascript arrays repeat


【解决方案1】:

在 ES6 中使用数组 fill() 方法

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

【讨论】:

  • Internet Explorer 和 Opera 尚不支持。
  • Node.js
  • 现有polyfill 供那些缺乏支持的人使用。
  • @Michael 你可以用Array(5).fill([1,2,3]).flat() 来做。请注意,flat() 仍处于试验阶段,浏览器支持较差。
  • 请注意,fill 的参数只计算一次,因此Array(9).fill(someMutable) 在数组中创建了九个对someMutable 的引用(改变一个会改变“它们全部”)。
【解决方案2】:
>>> 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]

【讨论】:

  • 愚蠢的问题,但是为什么 new Array(10).map 不起作用?
  • blazkovicz,原因见zertosh's comment on this answer
  • 使用 ES6,可以使用扩展运算符将其“升级”为 Array(...Array(10)).map(() =&gt; 5),也可以升级为 Array.from(Array(10)).map(() =&gt; 5)
  • 根据MDN,你可以这样:Array.from({length: 10}, () =&gt; 5);
  • @blazkovicz Array(10) 创建一个 lenght = 10 数组,没有任何可枚举的属性。 .map 仅适用于可枚举属性。 .apply 方法获取此数组,并将其映射到 arguments array(类似数组的对象),以传递给 Array 构造函数。参数数组不能是稀疏的,因此缺少的属性设置为 undefined 并变为可枚举的。现在我们可以按预期使用.map
【解决方案3】:

你可以试试:

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

另一种方法,不使用fillfrom,适用于任何长度的字符串:

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

同上answer。为了完整起见添加。

【讨论】:

  • 不错。最短更简单。
  • +1 用于简单处理。遗憾的是,您无法从中创建一个空字符串数组。除了那个非常聪明...
  • Array(6).join('a').split('a') 给了我一个空字符串数组。
  • 这仅适用于 1 个字符的字符串,因此不能完全回答问题。
  • @AlfonsoVergara:在 Javascript 中,String 是一种原始(值语义)类型;没有办法让两个字符串引用相同的数据(因为字符串 不是 Javascript 中的 引用;它们是值)。您必须注意对象和列表的引用语义,而不是字符串。
【解决方案4】:

你可以这样做:

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 而不是concat 来大大改进您的功能,因为concat 每次迭代都会创建一个新数组。像这样(仅作为如何使用数组的示例):

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

【讨论】:

  • 使用arr = new Array(len);预先分配所有条目会更有效,然后在循环中通过索引分配给它们,即arr[i] = value;。这样,您只需支付 O(n) 而不必随着数组的增长而不断重新分配数组。一般来说,尽可能通过追加来避免增长数组总是更好的。如果您知道最终尺寸,请使用它。
  • Array.from({length:5}).map(x =&gt; 2)
  • @noobninja:很好的解决方案;您应该重新输入它作为答案,以便对其进行投票。
  • 这是后者的优化版本:function fillArray(value, len) { for (let n = [], u = 0; u &lt; len; u++) n.push(value); return n }
【解决方案5】:

...和 ​​Array.fill() 来救援!

以前都是手动写的才知道这个??‍♂️


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

Array(4).fill(0)  // =>  [0, 0, 0, 0]

您还可以使用 fill() + map() 轻松创建顺序数组


Array(4).fill('').map((_, i) => i + ' ?') // =>  ['0 ?','1 ?','2 ?','3 ?']


Array(3).fill(' ?').map((flower, i) => i + flower) // =>  ['0 ?','1 ?','2 ?']


? 使用 .fill() 创建对象和数组时要小心,因为与原始类型不同,对象和数组是引用类型

这样,Javascript 会将所有创建的项目视为同一个对象,如果您想进一步使用创建的对象,这可能会导致您遇到错误

// ❌ Careful when using .fill() for this:

Array(3).fill({ value: 2 })  // =>  [{ value: 2 },{ value: 2 },{ value: 2 }]

上述行有效,但坚持使用 .fill().map() 模式会更安全。像这样:

// ?? Much better!

Array(3).fill().map(item => ({ value: 2 }))

【讨论】:

  • 注意IE不支持,但是你可以使用polyfill。
  • 我猜有很多 IE 不支持的东西...... :)
【解决方案6】:

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

或者创建一个值递增的数组

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

【讨论】:

  • 很好,如果您需要动态元素,这是最好的方法
  • Array.from({length:5}, i =&gt; 1) => iundefined,因为它代表空值 Array.from({length:5}, (e, i)=&gt;i) => eundefined,因为它代表空值。应该是Array.from({length:5}, v =&gt; 1)Array.from({length:5}, (v, i)=&gt;i)
【解决方案7】:

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

【讨论】:

  • _.times(length, _.constant(value))
  • 来自文档:_.fill(Array(3), 2);离ES6不远了
【解决方案8】:

如果你需要重复一个数组,使用下面的。

Array(3).fill(['a','b','c']).flat() 

会回来

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

【讨论】:

  • 使用现有数组的出色 oneliner,这是我所需要的。
  • Array(3).fill(['a','b','c']).flat()
【解决方案9】:

[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('') 不是更简单吗?为什么需要地图?
  • 返回 ["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] 

我应该注意,如果您使用 3rd-party 库,扩展内置对象的功能可能会导致问题。始终在您的决定中权衡这一点。

【讨论】:

  • 请注意,如果您将一个对象传递给fill,则数组中的每个索引都将引用同一个对象,因此更改一个将更改所有索引。如果它成为一个问题,这并不难解决。
  • 我不明白为什么许多 javascript 用户不知道不需要对原生函数进行原型设计。
  • 在 ES6 中添加了 fill method。所以我不建议在原型中添加你自己的东西,你会覆盖更快、更强大的版本。
  • @JanusTroelsen 为避免覆盖 javascript 或第三方库,您可以在声明之前检查是否存在。 if (!Array.prototype.fill) { }
  • @JanusTroelsen “真正的 polyfill”是什么意思?我用了一个polifyll。我的意思是:检查功能检测和实现以防万一。
【解决方案11】:

在 Node.js REPL 中:

> Array.from({length:5}).map(x => 2)
[ 2, 2, 2, 2, 2 ]
【解决方案12】:

如果您需要多次重复一个数组

var arrayA = ['a','b','c'];
var repeats = 3;
var arrayB = Array.apply(null, {length: repeats * arrayA.length})
        .map(function(e,i){return arrayA[i % arrayA.length]});
// result: arrayB = ['a','b','c','a','b','c','a','b','c']

灵感来自this answer

【讨论】:

【解决方案13】:

使用此功能:

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

【讨论】:

    【解决方案14】:

    没有更简单的方法。您需要创建一个循环并将元素推送到数组中。

    【讨论】:

    • 谢谢!在我接受之前,在效率方面是push 更好还是concat 更好?
    • CONCAT 需要检查两个数组,PUSH 只是添加了另一个元素,所以我希望 PUSH 通常更有效,但对于 IDENTICAL DATA,我认为 Guffa 的回答很到位。
    • 不需要循环,看我的回答。
    • @JanusTroelsen,除非您想要一种有效的方式来执行此操作,否则无需循环。你的是你能找到的较慢的实施之一。 push() to [] 是最快的。
    【解决方案15】:

    试试这个:

    "avinash ".repeat(5).trim().split(" ");
    

    【讨论】:

      【解决方案16】:

      您可以使用 SpreadOpeator 和 map() 函数创建一个数组,其中同一元素重复多次。

      function fillArray(value,len){
             return [...Array(len).keys()].map(x=> value);
         }
      

      【讨论】:

        【解决方案17】:

        此函数创建一个 (length) 元素数组,其中每个元素等于 (value),只要 (value) 是整数或整数字符串。任何十进制数字都将被截断。如果您确实需要十进制数,请将 "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]
        

        【讨论】:

          【解决方案18】:

          当我使用像这样的数组时,我遇到了上述方法的问题

          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
          【解决方案19】:

          另一条线:

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

          【讨论】:

            【解决方案20】:

            我今天在尝试不使用循环制作 2D 数组时发现了这一点。回想起来,加入一个新数组是很整洁的;我尝试映射一个新数组,但由于 map 会跳过空槽,因此该数组不起作用。

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

            “#”字符可以是任何有效的单个字符。 5 将是您想要的元素数量的变量。 7 将是您要填充数组的值。

            新的填充方法更好,我编码的时候不知道它存在,也不知道repeat是es6;我将写一篇博文,介绍如何将这个技巧与 reduce 结合使用来做一些很酷的事情。

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

            【讨论】:

              【解决方案21】:

              改进了Vivek's answer,这适用于任何长度的字符串,以填充长度为 n 的数组:Array(n+1).join('[string to be repeated][separator]').split('[separator]').slice(0, n)

              【讨论】:

                【解决方案22】:

                var finalAry = [..."2".repeat(5).split("")].map(Number);
                console.log(finalAry);

                【讨论】:

                  【解决方案23】:

                  如果您使用的是 lodash/underscore 之类的实用腰带,您可以这样做 :)

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

                  【讨论】:

                    【解决方案24】:

                    也可以用作单线:

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

                    【讨论】:

                      【解决方案25】:

                      这可能是另一个答案。

                      让卡片 = ["A","2","3","4","5","6","7","8","9","10","J" ,"Q","K"];

                      让 totalCards = [...cards, ...cards, ...cards, ...cards];

                      【讨论】:

                        【解决方案26】:

                        我需要一种方法来重复/循环一个数组(有 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"]
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-11-18
                          • 1970-01-01
                          • 2015-08-29
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多