83

有没有一种方法可以在javascript中生成字符或数字序列?

例如,我想创建包含八个1的数组。我可以用for循环来实现,但我想知道是否有jQuery库或javascript函数可以为我实现这一点?

5
  • 使用对于循环? 评论 2010年9月20日12:39
  • 1
    图书馆有必要做这项工作吗?我不这么认为=)
    – 用户372551
    评论 2010年9月20日12:41
  • 一点也不。这显然是最好在语言级别解决的问题,而不是在库级别。我相应地修改了这个问题。 评论 2010年9月20日12:43
  • 我认为这是一个非常有效的问题,有一些语言可以做到这一点,如果你必须每天/每月/每年创建3个下拉列表,那么3个for循环看起来很混乱,但它似乎也是唯一快速实现的方法
    – 罗布
    评论 2013年5月23日11:30

24个答案24

重置为默认值
80

原始问题已被编辑。因此,更新后的示例回答:

要填写相同的内容:

数组(8).fill(1)//=> [1, 1, 1, 1, 1, 1, 1, 1]

要填写从5开始的序列号:

数组(8).fill().map((元素,索引)=>索引+5)//=> [5, 6, 7, 8, 9, 10, 11, 12]

要填充序列字符,请从“G”开始:

数组(8).fill().map((element,index)=>String.fromCharCode('G'.charCodeAt(0)+index))//=>[“G”,“H”,“I”,“J”,“K”,“L”,“M”,“N”]
4
  • 11
    这也可以很容易地扩展到序列。。数组(8).fill().map((v,i)=>i)
    – 马特
    评论 2017年4月15日1:04
  • 1
    而且不需要新的
    – 马特
    评论 2017年4月15日4:05
  • 1
    或者,对于序列:[…Array(8)].map((_,i)=>i)
    – 淬火2
    评论 2018年2月23日12:06
  • 而且比数组.apply(0,…)技巧。
    – 智勇
    评论 2020年7月4日13:34
46

如果没有for循环,以下是一个解决方案:

Array.apply(0,Array(8)).map(function(){return 1;})

解释如下。

阵列(8)生成一个包含8个元素的稀疏数组未定义. The应用这个技巧会把它变成一个密集的数组。最后,使用地图,我们替换它未定义(相同的)价值1.

  • 这真的很酷,尽管我不太理解。Array.apply是如何将该数组转换为密集数组的?我很想确切地了解这个技巧中发生了什么。 评论 2013年2月7日6:47
  • 6
    下面是关于数组的简短解释:2ality.com/2012/06/dense-arrays.html. 评论 2013年2月10日4:39
  • 7
    我喜欢这个。在一次搜索中找到了它,它正是我想要的。下面是创建系列的一个小修改:数组.apply(0,数组(8)).map(函数(_,b){return b+1;})=>[1,2,3,4,5,6,7,8]要映射的参数是元素,索引,数组用于其他有趣的用途。
    – 驼背
    评论 2015年4月10日1:54
28

这是迄今为止最简单的一个

常量序列=[…数组(10).keys()]console.log(序列)

输出:[0,1,2,3,4,5,6,7,8,9]

1
  • 1
    不要继续阅读;没有比这更好的了。 评论 3月28日19:58
27

一个衬垫:

新数组(10).fill(1).map((_,i)=>i+1)

产量:

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
  • 新的必修的? 评论 2020年6月1日3:22
  • @javadba不需要,只是首选项。 评论 2020年9月3日13:04
  • 1
    也适用于fill() 评论 2022年6月1日14:02
19

我想您可以创建自己的可重用函数,例如:

函数makeArray(计数、内容){var结果=[];if(内容类型==“函数”){for(var i=0;i<计数;i++){result.prush(内容(i));}}其他{for(var i=0;i<计数;i++){结果推送(内容);}}返回结果;}

然后您可以执行以下任一操作:

var myArray=makeArray(8,1);//或者更复杂的东西,例如:var myArray=makeArray(8,函数(i){return i*3;});

你可以在这里试试请注意,上面的示例根本不依赖于jQuery,所以您可以在没有jQuery的情况下使用它。这样的事情你不会从库中获得任何东西:)

2
  • 我想结果。推动(i);应为`result.push(content);`啊。。。已编辑。。 评论 2010年9月20日12:43
  • 嘿,谢谢你。我想可能会有类似于MatLab中可用的内容,即创建包含特定元素的某个长度的向量。
    – 用户338195
    评论 2010年9月20日13:02
17
对于(var i=8,a=[];i--;)a.push(1);
  • 7
    需要moar jquery吗?嗯,这行得通吗:对于(var i=8,a=[];i--;)a.push($(1)); 评论 2010年9月20日12:44
  • @不是开玩笑的,OP可能不满意,因为它缺少jQuery,哈哈。在你的评论中a.推动($(1)),它将jQuery对象推送到数组中,而不是数字:)
    – 用户372551
    评论 2010年9月20日12:52
  • @我知道,阿维纳什只是在胡闹;) 评论 2010年9月20日19:08
16

2016年,Modern Browser功能问世。不需要一直使用jquery。

数组.from({length:8},(el,index)=>1/*或index*/);

您可以用一个简单的回调函数替换箭头函数,以访问更广泛的受支持浏览器。至少对我来说,这是一步迭代初始化数组的最简单方法。

注意:此解决方案不支持IE,但在developer.mozilla.org/。。。

  • 此代码返回:[ 1, 1, 1, 1, 1, 1, 1, 1 ]. 评论 2021年6月17日22:57
  • 正如问题所言,这是正确的。如果希望从1到8,请将1替换为索引+1 评论 2021年6月22日12:14
  • 1
    啊,是的,这就是问题,一组1。标题让我想到了一个序列,但我认为1仍然是一个序列。 评论 2021年6月23日0:48
12

使用Jquery:


$.map($(数组(8)),函数(val,i){return i;})

这将返回:

[0, 1, 2, 3, 4, 5, 6, 7]

$.map($(数组(8)),function(){return 1;})

这将返回:

[1, 1, 1, 1, 1, 1, 1, 1]

1
  • 1
    这个$在里面$(数组(8))这里不需要。只是$.map(数组(8),函数(){return 1;})就足够了。 评论 2015年1月30日6:57
8

范围(开始、结束、步骤):使用ES6 Iterator

您可以轻松创建范围()可以用作迭代器的生成器函数。这意味着您不必预先生成整个数组。

函数*范围(开始、结束、步长){让状态=开始;while(状态<结束){屈服状态;状态+=步骤;}回报;};

现在,您可能想创建一些从迭代器预生成数组并返回列表的东西。这对于接受数组的函数很有用。为此,我们可以使用数组.from()

const generate_array=(start,end,step)=>array.from(range(start、end、step));

现在您可以轻松生成静态数组,

const array=generate_array(1,10,2);

但当某些东西需要迭代器(或允许您选择使用迭代器)时,您也可以轻松创建一个迭代器。

for(范围常数i(1,Number.MAX_SAFE_INTEGER,7)){控制台.log(i)}
4

序列是一个流,它在需要时计算值。这只需要一个位内存,但在使用这些值时需要更多的CPU时间。

数组是预先计算的值的列表。这需要一些时间才能使用第一个值。它需要大量内存,因为序列的所有可能值都必须存储在内存中。你必须定义一个上限。

这意味着,在大多数情况下,创建具有序列值的数组不是一个好主意。相反,最好将序列实现为一个真正的序列,它仅受CPU的字长限制。

函数make_sequence(值,增量){如果(!value)值=0;if(!increment)increment=函数(值){返回值+1;};返回函数(){让电流=值;value=增量(值);回流;};}i=制造顺序()i()=>0i()=>1i()=>2j=make_sequence(1,函数(x){return x*2;})j()=>1j()=>2j()=>4j()=>8
2
  • 投票是因为我想了解闭包,我认为这是一个很好的例子,好吗?
    – 斯蒂布
    评论 2016年10月11日12:31
  • 1
    @stib完全正确。返回的匿名函数make_sequence(生成序列)捕获包含以下内容的环境价值增量,这意味着该函数具有对变量的读写访问权限。这才是最重要的。(词法)闭包只不过是一个动态生成的函数,它可以访问在创建函数的代码位置可见的环境。还有动态范围闭包,但除了Emacs之外,它们很少使用。
    – 切文
    评论 2016年10月11日13:32
1
定义8个1的数组的最快方法是定义它-变量A=[1,1,1,1,1,1,1,1];//你需要很多1才能让一个专用的函数有价值。//也许在《黑客帝国》中,当你想要很多史密斯的时候:Array.repeat=函数(val,len){对于(var i=len,a=[];i--;)a[i]=val;返回a;}var A=数组.repeat('Smith',100)/*返回值:(字符串)史密斯,史密斯,史密斯,史密斯*/
1
  • 应该是这样吗对于(var i=len;a=[];i--;)a[i]=val;(len后面是分号而不是逗号)?
    – 斯蒂布
    评论 2016年10月11日12:29
1

这是一个很好的选择

var结果=[];对于(var i=1;i!=4;++i)结果push(i)

查看此处了解更多选项https://ariya.io/2013/07/sequences-using-javascript-array

1
  • 就性能而言,根据我在V8上的基准测试,这个选项与我发布的速度选项差不多。如果您没有使用ES2022,这就是当前的性能赢家。请参阅stackoverflow.com/a/78103119/163170 评论 3月4日17:35
1

在ES6简单解决方案中:

seq=(from,len,step=1)=>数组.from({length:len},(el,i)=>from+(i*step));
0

基于Ariya Hidayat代码的Typescript方法:

/***从零开始生成数字序列。*@param{number}count结果数组中的数字计数。*@return{Array<number>}从零到(count-1)的数字序列。*/公共静态序列(计数:number):数组<number>{return Array.apply(0,Array(count)).map((x,i)=>{返回i;});}
0

如果你像我一样经常使用linspace,你可以像这样轻松地修改你的linspace版本:

函数linSeq(x0,xN){return linspace(x0,xN,Math.abs(xN-x0)+1);}函数linspace(x0,xN,n){dx=(xN-x0)/(n-1);变量x=[];对于(var i=0;i<n;++i){x.push(x0+i*dx);}返回x;}

然后可以在任何方向上使用linSeq,例如linSeq(2,4)生成2,3,4,而linSeg(4,2)生成4,3,2。

0

另一种方法,对于那些如何节省内存的学究来说:

Array.apply(null,Array(3)).map(Function.prototype.call.bind(Number))
0
var GetAutoNumber=导出。获取自动编号=(L)=>{让LeftPad=(number,targetLength)=>{让输出=数字+“”;while(output.length<targetLength){输出=“0”+输出;}返回输出;}设GivenLength的最大数字=“”;for(设t=0;t<L;t++){MaxNumberOfGivenLength=最大GivenLeng数+“9”}让StartTime=+new Date();让结果=[];let ReturnNumber;for(设i=1;i<=MaxNumberOfGivenLength;i++){结果推送(LeftPad(i,L))}for(设k=0;k!=26;k++){for(设j=0;j<=999;j++){结果推送(String.fromCharCode(k+65)+LeftPad(j,(L-1)));}}console.log(结果长度)返回结果;}获取自动编号(3)

它将生成类似于001-999、A01-A99…Z01-Z99的结果

0

如果你想产生一个等号序列,这是一个优雅的函数(解决方案类似于其他答案):

seq=(n,value)=>数组(n).fill(value)

如果你想产生一系列连续的数字,从0开始,这是一个很好的单线:

seq=n=>n<1?[]:[…序列(n-1),n]

这适用于不同的起始值和增量:

seq2=(n,开始,inc)=>seq(n).map(i=>start+inc*i)
0

下面是一个基准,每个选项后的注释显示了以毫秒为单位的1000次运行的中间时间:

让选择权=['数组(n).fill().map((_,i)=>i)',//2.71'数组(n).fill().map(函数(_,i){return i})',//2.73'让o=[];对于(设i=0;i<1e5;i++)o[i]=i',//3.29'让o=[];对于(设i=0;i<1e5;i++)o.push(i)',//3.31'让o=[];对于(设i=0,n2=n;i<n2;i++)o[i]=i',//3.38'让o=[];对于(设i=0;i<n;i++)o[i]=i',//3.57“Array.apply(null,Array(n)).map(Function.prototype.call.bind(Number))”,//3.64'数组.apply(0,数组(n)).map((_,i)=>i)',//3.73'数组.apply(null,数组(n)).map((_,i)=>i)',//3.77‘o2=[];对于(设i=0;i<n;i++)o2[i]=i',//4.42'[…数组(n).keys]',//7.07'数组.from({length:n},(_,i)=>i)',//7.13'来自数组(数组(n),(_,i)=>i)',//7.23'o3=[];对于(i3=0;i3<n;i3++)o3[i3]=i3'//24.34]设n=1e5opt.sort(()=>Math.random()-.5)for(让opt的opt){让t1=process.hrtime.bigint()评估(可选)让t2=进程.hrtime.bigint()控制台.log(t2-t1+'\t'+选项)}

这个对于当我使用块范围变量而不是全局变量时,循环变得更快了。

我使用中值时间而不是平均时间,因为偶尔一次跑步会比扭曲平均时间的典型跑步花费更长的时间。

我像这样运行基准测试对于{1..1000}中的i;do节点seqbench.js;完成,因为当我只调用脚本一次,但在脚本中运行每个选项1000次时,它受到某种优化的影响,其中对于循环成为最快的选择。

0

我喜欢这个。

函数*generate(){设索引=0;while(真){索引++;从CharCode生成String.from(64+索引)//这将从A返回,对于number只返回索引}}const gen=生成();console.log(gen.next().value);//console.log(gen.next().value);//B类console.log(gen.next().value);//C类
0

下面是一个使用迭代器类的选项,目前在V8上,该类的速度略快于其他答案:

数组(…新范围(0,n));

范围等级:

类别范围{第一;最后;构造函数(第一个,最后一个){this.first=第一个;this.last=最后;}[Symbol.iterator](){return this;}next(){return(this.first<this.last)返回? {value:this.first++,done:false}:{value:未定义,已完成:true};}}

最突出的竞争者是push(),尽管Range似乎快了一点(接近基准噪声的极限)。

我惊讶地发现速度慢了很多[…x]与相比阵列(…x),并惊讶地发现*发电机函数方法比上面显式的Range生成器类慢得多。

包裹next()String.fromCharCode中的表达式以适应字符。

-1

Javascript ES6正在运行:)

数组(8).fill(1)

console.log(数组(8).fill(1))

-2

为什么不只是简单的连接和拆分?

函数seq(len,value){//创建数组//使用我们想要的值进行连接//把它分开return(new Array(len+1)).join(value).split(“”);}seq(10,“a”);[“a”,“a”序列号(5,1);["1", "1", "1", "1", "1"]
-2

用JavaScript生成整数序列肯定会更方便。下面是一个递归函数,它返回一个整数数组。

函数intSequence(开始,结束,n=开始,arr=[]){返回n===结束?arr.concat(n):intSequence(开始,结束,开始<结束?n+1:n-1,arr.concat(n));}$>intSequence(1,1)<-数组[1]$>intSequence(1,3)<-数组(3)[1,2,3]$>intSequence(3,-3)<-数组(7)[3,2,1,0,-1,-2,-3]
1
  • 我认为可以肯定地说,您应该始终避免使用非常长的条件运算符(aka=>x?a:b)。特别是当你在做递归的时候。我的意思是,真的有必要用两行代码写这个函数吗? 评论 2020年8月5日14:05

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.