web-dev-qa-db-fra.com

Créer un tableau de tous les entiers compris entre deux nombres, inclus, en Javascript / jQuery

Disons que j'ai la case à cocher suivante:

<input type="checkbox" value="1-25" />

Pour obtenir les deux nombres qui définissent les limites de la plage que je recherche, j'utilise le jQuery suivant:

var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);

Comment puis-je créer un tableau contenant tous les entiers compris entre lowEnd et highEnd, y compris lowEnd et highEnd eux-mêmes? Pour cet exemple spécifique, évidemment, le tableau résultant serait:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
112
40 Degree Day
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
    list.Push(i);
}
144
Ben

En JavaScript ES6:

_function range(start, end) {
  return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
var result = range(9, 18); // [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
console.log(result);_

Pour être complet, le voici avec un paramètre optionnel step.

_function range(start, end, step = 1) {
  const len = Math.floor((end - start) / step) + 1
  return Array(len).fill().map((_, idx) => start + (idx * step))
}
var result = range(9, 18, 0.83);
console.log(result);_

Je voudrais utiliser range-inclusive à partir de npm dans un projet réel. Il prend même en charge les pas en arrière, alors c'est cool.

70
m59

Je recommande fortement les bibliothèques de soulignement ou de bas tirets:

http://underscorejs.org/#range

(Presque complètement compatible, apparemment lodash est plus rapide mais le soulignement a un meilleur doco à mon humble avis)

_.range([start], stop, [step])

Les deux bibliothèques ont un tas d'utilitaires très utiles.

35
ErichBSchulz

Cas d'utilisation

var genArr=(1)['..'](10)  //[1,2,3,4,5,6,7,8,9,10]

API;

Number.prototype['..']=function(to,step){
     var arr = [],from=this;
     while(from <= to){
        arr.Push(from++);
     }
     return arr;
};

FIDDLE:

http://jsfiddle.net/abdennour/mcpnvsmm/


ES6:

console.log(
   Array.from({length:10},(v,k)=>k+1)
)
28
Abdennour TOUMI

Ma version de la boucle;)

var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
   arr.Push(lowEnd++);
}
28

moyen le plus rapide

  1. while-- est plus rapide sur la plupart des navigateurs
  2. le réglage direct d'une variable est plus rapide que Push

une fonction:

var x=function(a,b,c,d){d=[];c=b-a+1;while(c--){d[c]=b--}return d},

theArray=x(lowEnd,highEnd);

ou

var arr=[],c=highEnd-lowEnd+1;
while(c--){arr[c]=highEnd--}

EDIT

version lisible

var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
 arr[c] = highEnd--
}

Démo

http://jsfiddle.net/W3CUn/

POUR LES DOWNVOTERS

performance

http://jsperf.com/for-Push-while-set/2

plus rapide dans ie et 3x plus rapidement dans firefox

uniquement sur aipad air, la boucle for est un peu plus rapide.

testé sur win8, osx10.8, ubuntu14.04, ipad, ipad air, ipod;

avec chrome, ff, ie safari, safari mobile.

je voudrais voir les performances sur les anciens navigateurs, c.-à-d. où la boucle for n'est pas optimisée!

16
cocco
function range(j, k) { 
    return Array
        .apply(null, Array((k - j) + 1))
        .map(function(_, n){ return n + j; }); 
}

c'est à peu près équivalent à

function range(j, k) { 
    var targetLength = (k - j) + 1;
    var a = Array(targetLength);
    var b = Array.apply(null, a);
    var c = b.map(function(_, n){ return n + j; });
    return c;
}

décomposer:

var targetLength = (k - j) + 1;

var a = Array(targetLength);

cela crée une matrice clairsemée de la longueur nominale correcte. Maintenant, le problème avec une matrice clairsemée est que, bien qu’elle ait la longueur nominale correcte, elle n’a pas d’éléments réels.

j = 7, k = 13

console.log(a);

nous donne

Array [ <7 empty slots> ]

Ensuite

var b = Array.apply(null, a);

transmet la matrice fragmentée sous forme de liste d'arguments au constructeur Array, qui produit une matrice dense de longueur (réelle) targetLength, où tous les éléments ont une valeur indéfinie. Le premier argument est la valeur 'this' pour le contexte d'exécution de la fonction constructeur du tableau. Il ne joue aucun rôle ici, il est donc nul.

Alors maintenant,

 console.log(b);

les rendements

 Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]

enfin

var c = b.map(function(_, n){ return n + j; });

utilise le fait que la fonction Array.map transmet: 1. la valeur de l'élément actuel et 2. l'index de l'élément actuel au délégué/rappel à la carte. Le premier argument est ignoré, alors que le second peut ensuite être utilisé pour définir la valeur de séquence correcte, après ajustement pour le décalage de début.

Donc alors

console.log(c);

les rendements

 Array [ 7, 8, 9, 10, 11, 12, 13 ]
11
david.barkhuizen

Si le début est toujours inférieur à la fin, on peut faire:

function range(start, end) {
  var myArray = [];
  for (var i = start; i <= end; i += 1) {
    myArray.Push(i);
  }
  return myArray;
};
console.log(range(4, 12));                 // → [4, 5, 6, 7, 8, 9, 10, 11, 12]

Si nous voulons pouvoir prendre un troisième argument pour pouvoir modifier l’étape utilisée pour construire le tableau, et le faire fonctionner même si le début est plus grand que la fin:

function otherRange(start, end, step) {
  otherArray = [];
  if (step == undefined) {
    step = 1;
  };
  if (step > 0) {
    for (var i = start; i <= end; i += step) {
      otherArray.Push(i);
    }
  } else {
    for (var i = start; i >= end; i += step) {
      otherArray.Push(i);
    }
  };
  return otherArray;
};
console.log(otherRange(10, 0, -2));        // → [10, 8, 6, 4, 2, 0]
console.log(otherRange(10, 15));           // → [10, 11, 12, 13, 14, 15]
console.log(otherRange(10, 20, 2));        // → [10, 12, 14, 16, 18, 20]

De cette façon, la fonction accepte les étapes positives et négatives et si aucune étape n'est indiquée, la valeur par défaut est 1.

6
drjorgepolanco

Mes cinq centimes:

Les deux sens Tableau de fonctions entières.

Lorsque la plage (0, 5) devient [0, 1, 2, 3, 4, 5].

Et gamme (5, 0) devient [5, 4, 3, 2, 1, 0].

Basé sur this réponse.

function range(start, end) {
  const isReverse = (start > end);
  const targetLength = isReverse ? (start - end) + 1 : (end - start ) + 1;
  const arr = new Array(targetLength);
  const b = Array.apply(null, arr);
  const result = b.map((discard, n) => {
    return (isReverse) ? n + end : n + start;
  });

  return (isReverse) ? result.reverse() : result;
}

P.S. Pour une utilisation réelle, vous devez également vérifier les arguments pour isFinite() et isNaN().

4
Sergei Panfilov

Vous pouvez concevoir une méthode de plage qui incrémente un nombre 'de' d'une quantité souhaitée jusqu'à atteindre un nombre 'à'. Cet exemple va "compter" vers le haut ou vers le bas, selon que sa taille est supérieure ou inférieure à sa valeur.

Array.range= function(from, to, step){
    if(typeof from== 'number'){
        var A= [from];
        step= typeof step== 'number'? Math.abs(step):1;
        if(from> to){
            while((from -= step)>= to) A.Push(from);
        }
        else{
            while((from += step)<= to) A.Push(from);
        }
        return A;
    }   
}

Si vous souhaitez un pas décimal: Array.range (0,1, .01), vous devez tronquer les valeurs de toute imprécision en virgule flottante. Sinon, vous retournerez des nombres tels que 0.060000000000000005 au lieu de .06.

Cela ajoute un peu de surcharge à l’autre version, mais fonctionne correctement pour les étapes entières ou décimales.

Array.range= function(from, to, step, prec){
    if(typeof from== 'number'){
        var A= [from];
        step= typeof step== 'number'? Math.abs(step):1;
        if(!prec){
            prec= (from+step)%1? String((from+step)%1).length+1:0;
        }
        if(from> to){
            while(+(from -= step).toFixed(prec)>= to) A.Push(+from.toFixed(prec));
        }
        else{
            while(+(from += step).toFixed(prec)<= to) A.Push(+from.toFixed(prec));
        }
        return A;
    }   
}
4
kennebec
var values = $(this).val().split('-'),
    i = +values[0],
    l = +values[1],
    range = [];

while (i < l) {
    range[range.length] = i;
    i += 1;
}

range[range.length] = l;

Il y a probablement une façon plus sèche de faire la boucle, mais c'est l'idée de base.

4
sdleihssirhc
function createNumberArray(lowEnd, highEnd) {
    var start = lowEnd;
    var array = [start];
    while (start < highEnd) {
        array.Push(start);
        start++;
    }
} 
4
Igor

Ajout de http://minifiedjs.com/ à la liste des réponses :)

Le code est semblable au soulignement et aux autres:

var l123 = _.range(1, 4);      // same as _(1, 2, 3)
var l0123 = _.range(3);        // same as _(0, 1, 2)
var neg123 = _.range(-3, 0);   // same as _(-3, -2, -1)
var empty = _.range(2,1);      // same as _()

Documents ici: http://minifiedjs.com/api/range.html

J'utilise minified.js car il résout tous mes problèmes de faible encombrement et de syntaxe facile à comprendre. Pour moi, il remplace JQuery, MoustacheJS et Underscore/SugarJS dans un seul et même cadre.

Bien sûr, ce n’est pas aussi populaire que le soulignement. Cela pourrait être une préoccupation pour certains.

Minified a été mis à disposition par Tim Jansen en utilisant la licence CC-0 (domaine public).

2
Christian
        function getRange(a,b)
        {
            ar = new Array();
            var y = a - b > 0 ? a - b : b - a;
            for (i=1;i<y;i++)
            {
                ar.Push(i+b);
            }
            return ar;
        }
1
Mamdouh

Résoudre en nderscore

data = [];
_.times( highEnd, function( n ){ data.Push( lowEnd ++ ) } );
0
vladiim