web-dev-qa-db-fra.com

Créer un tableau de caractères de la plage spécifiée

J'ai lu un code où quelqu'un a fait cela en Ruby:

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

sortie:

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

Y a-t-il quelque chose dans Javascript qui permettra de le faire aussi facilement? Si non, y a-t-il un module Node qui permet quelque chose de similaire?

17
EhevuTov

Javascript n'a pas cette fonctionnalité de manière native. Vous trouverez ci-dessous quelques exemples de solutions possibles:

Fonction normale, tous les caractères du plan de base (aucune vérification des paires de substitution) 

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

Les mêmes que ci-dessus, mais en tant que fonction ajoutée au prototype de tableau, et donc disponible pour tous les tableaux: 

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

Une plage de caractères présélectionnés. Est plus rapide que les fonctions ci-dessus et vous permet d'utiliser alphanum_range('A','z') pour signifier A-Z et 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();

Ou n'importe quel personnage de la gamme ascii. En utilisant un tableau mis en cache, il est plus rapide que les fonctions qui construisent le tableau à chaque fois.

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

Si vous utilisez ES6, vous pouvez générer une séquence à l’aide de Array.from () en transmettant un objet de type tableau pour la longueur de la plage et une fonction de carte comme second argument pour convertir le clé de tableau de chaque élément de la plage en caractère à l'aide de String.fromCharCode ():

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

Vous pouvez également utiliser le constructeur Array (note: ES6 permet aux constructeurs d'être appelés avec un appel de fonction ou avec l'opérateur new) pour initialiser un tableau de la longueur par défaut souhaitée. Remplissez-le à l'aide de Array.fill () , puis mappez-le:

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

La même chose peut être accomplie avec l’opérateur spread :

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

Les trois exemples ci-dessus renverront un tableau avec des caractères de A à Z. Pour les plages personnalisées, vous pouvez ajuster la longueur et le caractère de départ.

Pour les navigateurs qui ne prennent pas en charge ES6, vous pouvez utiliser babel-polyfill ou core-js polyfill (core-js/fn/array/from).

Si vous ciblez ES5, je recommanderais la solution Array.apply de @wires qui est très similaire à celle-ci.

Enfin, Underscore/Lodash et Ramda ont une fonction range ():

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

La fonction .map pourrait être un générateur de fonctions pouvant être utilisé pour différents jeux de caractères.

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

Et vous voudrez peut-être aussi créer un assistant de tableau "complet".

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

Ensuite, utilisez-les comme ça.

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

TL; DR

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

Ou même

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"

Je pense que cela peut être exprimé le plus clairement de manière fonctionnelle: mappez [0 .. 25] à ['a' .. 'z'].

Nous pouvons utiliser fromCharCode(n) pour convertir un nombre en chaîne. Pour trouver la valeur numérique correspondant à un caractère, nous avons besoin de sa fonction inverse, toCharCode(s):

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

Alors le reste est facile:

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

Construit un tableau de 26 non défini: [undefined, ... , undefined]. Puis map index i de chaque valeur à 97 + i == 'a'.charCodeAt(0) + i (pour les majuscules, commencez par 'A' => 65).

Cette première ligne pourrait nécessiter des explications. Ce que nous faisons effectivement est identique à Array(1,2,3) == [1,2,3]. Au lieu de passer un tableau réel à apply, nous transmettons quelque chose qui s'agite comme un tableau (possède la propriété length). Cela entraîne l'appel de Array(undefined, .. , undefined).

Voir apply And "objet de type tableau générique" Pour plus d'informations.

5
wires

Regardez la réponse de Kannebec pour une question similaire.

JavaScript a-t-il une méthode comme "range ()" pour générer un tableau basé sur les limites fournies?

Si vous ne voulez pas ajouter une fonction propre, mais sur une ligne:

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 compile en javascript, et il a des plages numériques:

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

Voici un lien vers ce script sur le site coffeescript.org. Vous pouvez voir en quoi javascript est compilé et l'exécuter en direct dans votre navigateur.

(Et oui , vous pouvez utiliser coffeescript pour Node.js)

3
Mark Thomas

Non, JavaScript n'a pas d'objet Range intégré. Vous devez écrire une fonction pour créer une plage abstraite, puis ajouter une méthode to_a pour l'équivalence.

Pour le plaisir, voici une autre façon d’obtenir cette sortie exacte, sans chaîne intermédiaire.

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"

Pour Node.js, il existe le module Lazy .

1
Phrogz

Approche légèrement différente

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

empreintes

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1
test30

Peut-être que cette fonction vous aidera.

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"]

Ce n'est pas le mien, tiré de: http://javascript.ru/php/range

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

donne la plage a-z, mais j’aime bien l’option de fonction de certains aussi.

0
Jonathan Joosten
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