web-dev-qa-db-ja.com

指定された範囲から文字の配列を作成します

私は誰かが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には、これを同じくらい簡単に実行できる何かがありますか?そうでない場合、Node同様のことができるモジュールはありますか?

28
EhevuTov

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();
_
15
some

ES6を使用している場合は、配列の長さを配列のようなオブジェクトに渡し、変換する2番目の引数としてマップ関数を渡すことにより、 Array.from() を使用してシーケンスを生成できますString.fromCharCode()を使用して、範囲内の各アイテムの配列キーを文字に変換します。

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

また、Arrayコンストラクター(注:ES6ではコンストラクターを関数呼び出しまたはnew演算子で呼び出すことができます)を使用して、目的のデフォルトの長さの配列を初期化し、 Array .fill() 、次にそれをマッピングします:

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

スプレッド演算子 でも同じことができます。

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

上記の3つの例は、AからZまでの文字を含む配列を返します。カスタム範囲の場合、長さと開始文字を調整できます。

ES6をサポートしていないブラウザーの場合は、babel-polyfillまたはcore-js polyfill(core-js/fn/array/from)を使用できます。

ES5をターゲットにしている場合は、 Array.apply solution by @wires をお勧めします。これは、これと非常によく似ています。

最後に、アンダースコア/ロダッシュとラムダにはrange()関数があります:

_.range('A'.charCodeAt(0), 'Z'.charCodeAt(0) + 1).map(i => String.fromCharCode(i));
17
Brian Stanback
var chars = [].concat.apply([], Array(26))
              .map(function(_, i) { return String.fromCharCode(i+65); })
              .join();

.map functionは、さまざまな文字セットに使用できる関数ジェネレーターである可能性があります。

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

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)が呼び出されます。

詳細は apply および "generic array-like object" を参照してください。

5
wires

同様の質問については、kannebecの回答をご覧ください。

JavaScriptには、指定された境界に基づいて配列を生成する「range()」のようなメソッドがありますか?

独自の関数を追加したくないが、1行で:

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

CoffeeScript はJavaScriptにコンパイルされ、数値の範囲があります。

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

リンクはこちら coffeescript.orgサイトにあるこのスクリプトへ。コンパイルするJavaScriptを確認し、ブラウザでライブで実行できます。

(そして yes 、Node.jsにcoffeescriptを使用できます)

3
Mark Thomas

いいえ、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 モジュールがあります。

1
Phrogz

少し異なるアプローチ

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

プリント

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1
test30

多分この機能はあなたを助けるでしょう。

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

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

範囲a-zを指定しますが、一部の関数オプションも好きです。

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", ",");
0
Diode