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

时间:2012-09-11 19:49:08

标签: javascript ruby node.js

我读了一些代码,其中某人在Ruby中做了这个:

puts ('A'..'Z').to_a.join(',')

输出:

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

Javascript中是否有某些内容可以轻松完成?如果没有,是否有节点模块允许类似的东西?

12 个答案:

答案 0 :(得分:15)

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

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

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

预选字符的范围。比上面的函数更快,让你使用alphanum_range('A','z')来表示A-Z和a-z:

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

或来自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();

答案 1 :(得分:14)

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

将范围中的每个项的键转换为字符
Array.from({ length: 26 }, (_, i) => String.fromCharCode('A'.charCodeAt(0) + i));

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

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

使用Array.fill()

可以实现同样的目标
[...Array(26)].map((_, i) => String.fromCharCode('A'.charCodeAt(0) + i));

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

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

如果您要定位ES5,我会推荐spread operator,这与此非常相似。

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

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

答案 2 :(得分:7)

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

.map函数可以是一个函数生成器,可以用于不同的字符集。

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

您可能还想创建一个“完整”数组助手。

function fullArray(len) { return [].concat.apply([], Array(len)); }

然后像这样使用它们。

var chars = fullArray(26).map(charRange("A"))
                         .join();

答案 3 :(得分:5)

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

Does JavaScript have a method like "range()" to generate an array based on supplied bounds?

如果您不想添加自己的功能,只需一行:

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

答案 4 :(得分:5)

<强> TL; DR

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

甚至

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"

我认为这可以通过功能性方式表达得最清楚:将[0 .. 25]映射到['a' .. 'z']

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

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

然后其余的很容易:

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

构造一个包含26个未定义的数组:[undefined, ... , undefined]。然后map将每个值的i索引97 + i'a'.charCodeAt(0) + i == 'A' => 65(大写字母从Array(1,2,3)开始)。

这第一行可能需要一些解释。我们实际做的与[1,2,3] == apply相同。我们不是将实际数组传递给length,而是传递像数组一样嘎嘎叫的东西(具有Array(undefined, .. , undefined)属性)。这导致调用{{1}}。

请参阅 apply"generic array-like object" 了解更多信息。

答案 5 :(得分:3)

CoffeeScript编译为javascript,它有数字范围:

(String.fromCharCode(x+64) for x in [1..26]).join(",")

Here's a link到coffeescript.org网站上的这个脚本。你可以看到它编译的javascript,并在你的浏览器中实时运行。

(和yes,你可以使用coffeescript for Node.js)

答案 6 :(得分:1)

也许这个功能可以帮到你。

function range ( low, high, step ) {    // Create an array containing a range of elements
    // 
    // +   original by: _argos

    var matrix = [];
    var inival, endval, plus;
    var walker = step || 1;
    var chars  = false;

    if ( !isNaN ( low ) && !isNaN ( high ) ) {
        inival = low;
        endval = high;
    } else if ( isNaN ( low ) && isNaN ( high ) ) {
        chars = true;
        inival = low.charCodeAt ( 0 );
        endval = high.charCodeAt ( 0 );
    } else {
        inival = ( isNaN ( low ) ? 0 : low );
        endval = ( isNaN ( high ) ? 0 : high );
    }

    plus = ( ( inival > endval ) ? false : true );
    if ( plus ) {
        while ( inival <= endval ) {
            matrix.push ( ( ( chars ) ? String.fromCharCode ( inival ) : inival ) );
            inival += walker;
        }
    } else {
        while ( inival >= endval ) {
            matrix.push ( ( ( chars ) ? String.fromCharCode ( inival ) : inival ) );
            inival -= walker;
        }
    }

    return matrix;
}

console.log(range('A','Z')) 
// ["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"]

这不是我的,取自:http://javascript.ru/php/range

答案 7 :(得分:1)

不,JavaScript没有任何内置的Range对象。您需要编写一个函数来创建一个抽象Range,然后为等价添加to_a方法。

为了好玩,这里有一种获得确切输出的替代方法,没有中间字符串。

function commaRange(startChar,endChar){
  var c=','.charCodeAt(0);
  for (var a=[],i=startChar.charCodeAt(0),e=endChar.charCodeAt(0);i<=e;++i){
    a.push(i); a.push(c);
  }
  a.pop();
  return String.fromCharCode.apply(String,a);
}

console.log(commaRange('A','J')); // "A,B,C,D,E,F,G,H,I,J"

对于Node.js,有Lazy模块。

答案 8 :(得分:1)

略有不同的方法

String.fromCharCode(..." ".repeat(26).split("").map((e,i)=>i+'A'.charCodeAt()))

打印

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

答案 9 :(得分:0)

function range(r, x) {
    var c1 = r.charCodeAt(0)+1, c2 = r.charCodeAt(3), s = r[0];
    if(c1 && c2)while (c1 <= c2) s += (x || "") + String.fromCharCode(c1++);
    return s;
}

range("A--S", ",");

答案 10 :(得分:0)

var range = [];
for(var i = 65; i < 91; i++)
{
 range.push(String.fromCharCode(i));
}
range = range.join(',');

给出范围a-z,但我也喜欢一些函数选项。

答案 11 :(得分:0)

https://stackoverflow.com/a/64599169/8784402

单线生成字符列表

const charList = (a,z,d=1)=>(a=a.charCodeAt(),z=z.charCodeAt(),[...Array(Math.floor((z-a)/d)+1)].map((_,i)=>String.fromCharCode(a+i*d)));

console.log("from A to G", charList('A', 'G'));
console.log("from A to Z with step/delta of 2", charList('A', 'Z', 2));
console.log("reverse order from Z to P", charList('Z', 'P', -1));
console.log("from 0 to 5", charList('0', '5', 1));
console.log("from 9 to 5", charList('9', '5', -1));
console.log("from 0 to 8 with step 2", charList('0', '8', 2));
console.log("from α to ω", charList('α', 'ω'));
console.log("Hindi characters from क to ह", charList('क', 'ह'));
console.log("Russian characters from А to Я", charList('А', 'Я'));

对于TypeScript
const charList = (p: string, q: string, d = 1) => {
  const a = p.charCodeAt(0),
    z = q.charCodeAt(0);
  return [...Array(Math.floor((z - a) / d) + 1)].map((_, i) =>
    String.fromCharCode(a + i * d)
  );
};