JavaScript - 创建简单的动态数组

48

创建这个简单数组的最有效方法是什么?

var arr = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];

假设我们可以从一个变量中得到数字10

var mynumber = 10;

尾递归会更加高级。 - joshp
@joshp 好吧,他确实说了“最有效率”,所以我会选择使用for循环 :P - Selvakumar Arumugam
4
你真的希望将这些数字存储为字符串吗? - BiAiB
我不知道JS环境是否优化尾递归。如果是的话,它们将是等效的。我主要考虑时尚方面。 - joshp
3
有趣的是,有人花时间回复,但并没有提供有建设性的意见。 - Sam
17个回答

89
var arr = [];
for(var i=1; i<=mynumber; i++) {
   arr.push(i.toString());
}

1
在每个循环中扩展数组并不是很健康的做法,但大多数情况下这几乎是不可避免的。但是这次我们知道数组的长度。(有关更多信息请参见我的答案) - ajax333221

28

使用 Array.from 方法,可以在一句表达中简明地实现这一点,这是在 ES2015 中实现的:

Array.from({ length: 10 }, (_, idx) => `${++idx}`)

from的第一个参数是类似数组的对象,它提供了一个长度属性。第二个参数是一个映射函数,允许我们用所请求的调整后的索引值替换默认的undefined值。在这里查看规范.


有一件事需要提醒:您可以使用任何变量名来代替“_”,map函数的第一个属性表示数组元素的当前值(arr[idx])。在这个例子中,它始终是“undefined”。 - Lusk116

17

更新:像这样的微优化并不值得,现在的引擎都非常智能,在2020年我建议只需使用var arr = [];

以下是我的实现方式:

var mynumber = 10;
var arr = new Array(mynumber);

for (var i = 0; i < mynumber; i++) {
    arr[i] = (i + 1).toString();
}

我的答案与众不同之处在于,我做了一些不同的事情:

  • 最好指定数组长度,而不是每次都强制扩展

所以我使用 new Array(mynumber); 创建了数组。


3
为什么在每次迭代中扩展数组是不好/不建议的?它会影响内存分配或存储值所需的时间吗?能否详细说明其缺点? - Yash Kalwani
@YashKalwani 基本上就像复制和粘贴一样。如果我们没有在内存中分配固定大小,可能会有一个新项目放置在上一个索引附近。因此编译器将指示操作系统将其复制到另一个位置,然后插入它。 - thatcoder

11
这篇文章是关于“如何动态创建数组而不使用循环”的。字面量操作符“[]”不能让我们动态创建,所以让我们看看Array、它的构造函数和它的方法。在ES2015中,Array有一个方法.from(),它可以轻松地让我们创建动态数组:
Array.from({length: 10}) // -> [undefined, undefined, undefined, ... ]

当数组的构造函数接收数字作为第一个参数时,它将创建一个具有该数字大小的数组,但它不可迭代,因此我们无法使用.map().filter()等方法:

new Array(10) // -> [empty × 10]

但是,如果我们传递多个参数,我们将收到所有参数的数组:

new Array(1,2,3) // -> [1,2,3]

如果我们使用ES2015,我们可以使用展开运算符将空数组展开到另一个数组中,这样我们将会得到可迭代的数组:
[...new Array(10)]  // -> [undefined, undefined, undefined, ...]

但是如果我们不使用ES2015并且没有polyfills,也可以在ES5中创建动态数组而无需循环。如果我们考虑.apply()方法:它会将第二个参数数组扩展为参数。因此,在Array的构造函数上调用apply就可以完成这个任务:

Array.apply(null, new Array(10))  // -> [undefined, undefined, undefined, ...]

在我们有了动态可迭代的数组之后,我们可以使用 map 来分配动态值:
Array.apply(null, new Array(10)).map(function(el, i) {return ++i + ""})

// ["1","2","3", ...]

@NickA,谢谢你的留言。我已经添加了解释。 - Anton Temchenko
啊,大有改善,好多了 :) - Nick stands with Ukraine

4
听起来你只是想构建一个包含整数值字符串版本的数组。一个简单的方法是:
var arr = [];
for (var i = 1; i <= mynumber; i++) arr.push(""+i);

如果您想要更有趣的版本,可以使用一个生成器...

function tail(i, maxval) {
    return [i].concat(i < maxval ? tail(i+1, maxval) : []);
}

var arr = tail(1, mynumber);

如果mynumber在tail函数内部是本地的,那么速度会更快。 - Larry Battle
没错 - 虽然我曾经考虑过Python中的range(START, STOP, STRIDE)函数。 - koblas

2
var arr = [];
while(mynumber--) {
    arr[mynumber] = String(mynumber+1);
}

这是我的第一个想法。高效而简洁。 - Erik Reppen
在这些示例中,将整数数组连接/重新拆分可能比逐个转换更快。例如,在循环之后:arr=arr.join('_').split('_'); 并且移除 String(<number>) 步骤。 - Erik Reppen

2
我会按照以下步骤进行: ;

var num = 10,
  dynar = [...Array(num)].map((_,i) => ++i+"");
console.log(dynar);


2

由于之前的回答都没有提供使用 repeat 生成动态数组的解决方案,因此在这里为您提供:
使用 repeat 生成包含十个数字的动态数组:

[...'x'.repeat(10).split('').keys()]
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

为了得到你想要的:

var arr = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];

只需将所有元素的键加一(因为数组是从零开始)并通过字符串字面量.toString()甚至只需将空格添加到数字''+x来将数字转换为字符串。
let mynumber = 10;

const keys = [...'x'.repeat(mynumber).split('').keys()]
const arr = keys.map(x=>`${x+1}`);
//['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

这是一个好的回答,帮助我解决了我的问题。谢谢。 - raddevus

2
有点晚了,但现在使用ES6可以做一些非常酷的事情。您现在可以在一行代码中用随机数字填充动态长度的数组!
[...Array(10).keys()].map(() => Math.floor(Math.random() * 100))

你可以使用 Array.from({length:10}, _=>-~(Math.random() * 100)) 这段代码。 - undefined

1

误读了问题,已更正。请尝试:

var myNumber = 100,
    myarr = (function arr(i){return i ? arr(i-1).concat(i) : [i]}(myNumber));

只是为了好玩,如果你像这样扩展Array

Array.prototype.mapx = function(callback){
  return String(this).split(',').map(callback);
}

您可以使用:

var myNum = 100, 
    myarr = new Array(myNum).mapx(function(el,i){return i+1;});

1
好的,现在我将更改 mynumber = 100; 。请为我编写长字符串。 - Selvakumar Arumugam
看我的修改。我想在 CPU 周期方面它并不是很高效,但它很简短。 - KooiInc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接