Create an array of characters from specified range

后端 未结 12 2183
名媛妹妹
名媛妹妹 2020-12-17 08:19

I read some code where someone did this in Ruby:

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

output:

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O         


        
相关标签:
12条回答
  • 2020-12-17 08:56
    var chars = [].concat.apply([], Array(26))
                  .map(function(_, i) { return String.fromCharCode(i+65); })
                  .join();
    

    The .map function could be a function generator that could be used for different character sets.

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

    And you may also want to create a "full" Array helper.

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

    Then use them like this.

    var chars = fullArray(26).map(charRange("A"))
                             .join();
    
    0 讨论(0)
  • 2020-12-17 08:56

    TL;DR

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

    Or even

    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"
    

    I think this can be expressed clearest in a functional way: map [0 .. 25] to ['a' .. 'z'].

    We can use fromCharCode(n) to convert a number into a string. To find the numerical value corresponding to a character we need it's inverse function, toCharCode(s):

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

    Then the rest is easy:

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

    Constructs an array of 26 undefined's: [undefined, ... , undefined]. Then map index i of each value to 97 + i == 'a'.charCodeAt(0) + i (for uppercase start at 'A' => 65).

    This first line might need some explanation. What we are effectively doing is the same as Array(1,2,3) == [1,2,3]. Instead of passing an actual array to apply, we pass something that quacks like an array (has the length property). This results in calling Array(undefined, .. , undefined).

    See apply and "generic array-like object" for more infomation.

    0 讨论(0)
  • 2020-12-17 09:00

    Javascript doesn't have that functionality natively. Below you find some examples of how it could be solved:

    Normal function, any characters from the base plane (no checking for surrogate pairs)

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

    The same as above, but as a function added to the array prototype, and therefore available to all arrays:

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

    A range from preselected characters. Is faster than the functions above, and let you use alphanum_range('A','z') to mean A-Z and 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();
    

    Or any character from the ascii range. By using a cached array, it is faster than the functions that build the array every time.

    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();
    
    0 讨论(0)
  • 2020-12-17 09:00
    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", ",");
    
    0 讨论(0)
  • 2020-12-17 09:03

    Slightly different approach

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

    prints

    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    0 讨论(0)
  • 2020-12-17 09:09

    Take a look at the answer from kannebec for a similar question.

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

    If you don't want to add an own function, but in one line:

    var abc = 
    (function(){var output = []; for(var i='A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++)
        output.push(String.fromCharCode(i)); return output;})().join(',');
    
    0 讨论(0)
提交回复
热议问题