从指定范围创建一个字符数组

Ehe*_*Tov 25 javascript ruby node.js

我读了一些代码,其中有人用Ruby做过这个:

puts ('A'..'Z').to_a.join(',')
Run Code Online (Sandbox Code Playgroud)

输出:

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
Run Code Online (Sandbox Code Playgroud)

有什么东西Javascript可以让这一切变得容易吗?如果没有,是否有节点模块允许类似的东西?

小智 18

如果你正在使用ES6,你可以使用Array.from()生成一个序列,通过传入一个类似于数组的对象作为范围的长度,并使用map函数作为第二个参数来转换每个项目的数组键.使用String.fromCharCode()将字符转换为字符:

Array.from({ length: 26 }, (_, i) => String.fromCharCode('A'.charCodeAt(0) + i));
Run Code Online (Sandbox Code Playgroud)

您还可以使用Array构造函数(注意:ES6允许通过函数调用或使用new运算符调用构造函数)来初始化所需默认长度的数组,使用Array.fill()填充它,然后通过它进行映射:

Array(26).fill().map((_, i) => String.fromCharCode('A'.charCodeAt(0) + i));
Run Code Online (Sandbox Code Playgroud)

扩展运算符可以实现同样的目的:

[...Array(26)].map((_, i) => String.fromCharCode('A'.charCodeAt(0) + i));
Run Code Online (Sandbox Code Playgroud)

以上三个示例将返回一个包含从A到Z的字符的数组.对于自定义范围,您可以调整长度和起始字符.

对于不支持ES6的浏览器,您可以使用babel-polyfill或core-js polyfill(core-js/fn/array/from).

如果你的目标是ES5,我会推荐@wires的Array.apply解决方案,它与这个解决方案非常相似.

最后,Underscore/Lodash和Ramda有一个range()函数:

_.range('A'.charCodeAt(0), 'Z'.charCodeAt(0) + 1).map(i => String.fromCharCode(i));
Run Code Online (Sandbox Code Playgroud)


som*_*ome 16

Javascript本身没有该功能.下面是一些如何解决它的例子:

正常功能,基准平面中的任何字符(不检查代理对)

function range(start,stop) {
  var result=[];
  for (var idx=start.charCodeAt(0),end=stop.charCodeAt(0); idx <=end; ++idx){
    result.push(String.fromCharCode(idx));
  }
  return result;
};

range('A','Z').join();
Run Code Online (Sandbox Code Playgroud)

与上面相同,但作为添加到数组原型的函数,因此可用于所有数组:

Array.prototype.add_range = function(start,stop) {
  for (var idx=start.charCodeAt(0),end=stop.charCodeAt(0); idx <=end; ++idx){
    this.push(String.fromCharCode(idx));
  }
  return this;
};

[].add_range('A','Z').join();
Run Code Online (Sandbox Code Playgroud)

预选字符的范围.比上面的函数更快,让你alphanum_range('A','z')用来表示AZ和az:

var alphanum_range = (function() {
  var data = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');
  return function (start,stop) {
    start = data.indexOf(start);
    stop = data.indexOf(stop);
    return (!~start || !~stop) ? null : data.slice(start,stop+1);
  };
})();

alphanum_range('A','Z').join();
Run Code Online (Sandbox Code Playgroud)

或者来自ascii范围的任何字符.通过使用缓存数组,它比每次构建数组的函数更快.

var ascii_range = (function() {
  var data = [];
  while (data.length < 128) data.push(String.fromCharCode(data.length));
  return function (start,stop) {
    start = start.charCodeAt(0);
    stop = stop.charCodeAt(0);
    return (start < 0 || start > 127 || stop < 0 || stop > 127) ? null : data.slice(start,stop+1);
  };
})();

ascii_range('A','Z').join();
Run Code Online (Sandbox Code Playgroud)


gra*_*ing 7

var chars = [].concat.apply([], Array(26))
              .map(function(_, i) { return String.fromCharCode(i+65); })
              .join();
Run Code Online (Sandbox Code Playgroud)

.map函数可以是可用于不同字符集的函数发生器.

function charRange(start) {
    var base = start.charCodeAt(0);
    return function(_, i) { return String.fromCharCode(i + base); };
}
Run Code Online (Sandbox Code Playgroud)

您可能还想创建一个"完整"数组助手.

function fullArray(len) { return [].concat.apply([], Array(len)); }
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它们.

var chars = fullArray(26).map(charRange("A"))
                         .join();
Run Code Online (Sandbox Code Playgroud)


Mar*_*idt 5

看看kannebec给出类似问题的答案.

JavaScript是否有像"range()"这样的方法来根据提供的边界生成数组?

如果您不想添加自己的功能,但在一行中:

var abc = 
(function(){var output = []; for(var i='A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++)
    output.push(String.fromCharCode(i)); return output;})().join(',');
Run Code Online (Sandbox Code Playgroud)


wir*_*res 5

TL; DR

// ['a', .. , 'z']
Array.apply(null, {length: 26})
    .map(function (x,i) { return String.fromCharCode(97 + i) });
Run Code Online (Sandbox Code Playgroud)

甚至

function range(first, last) {
    var a = first.charCodeAt(0)
    var b = last.charCodeAt(0) + 1
    return Array.apply(null, {length: Math.abs(b - a)})
      .map(function (x,i) { return String.fromCharCode(Math.min(a, b) + i) });
}
range('K','M') // => ['K','L','M']
range('$','z') // => "$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz"
Run Code Online (Sandbox Code Playgroud)

我认为这可以用一种功能性的方式表达得最清楚:map [0 .. 25]to ['a' .. 'z'].

我们可以使用fromCharCode(n)将数字转换为字符串.要找到与字符对应的数值,我们需要它的反函数,toCharCode(s):

var toCharCode = function(s){ return s.charCodeAt(0) } // 'a' => 97, 'b' => 98, ..
Run Code Online (Sandbox Code Playgroud)

其余的很简单:

Array.apply(null, {length: 26})
     .map(function (x,i) { return String.fromCharCode(97 + i) });
Run Code Online (Sandbox Code Playgroud)

构造一个由26个undefined组成的数组:[undefined, ... , undefined].然后将每个值的map索引转换i97 + i== 'a'.charCodeAt(0) + i(对于大写的起始位置'A' => 65).

第一行可能需要一些解释.我们实际做的是和Array(1,2,3)==一样[1,2,3].我们不是传递一个实际的数组apply,而是传递像数组一样嘎嘎叫的东西(具有length属性).这导致了呼唤Array(undefined, .. , undefined).

有关 详细信息,请参阅 apply"类通用数组对象".