Comment obtenir un sous-tableau à partir d'un tableau?

263

J'ai var ar = [1, 2, 3, 4, 5]et veux une fonction getSubarray(array, fromIndex, toIndex), le résultat de l'appel getSubarray(ar, 1, 3)est un nouveau tableau [2, 3, 4].

Sergey Metlov
la source
10
Avez-vous essayé Slice ?
Tom Knapen

Réponses:

408

Jeter un coup d'œil à Array.slice(begin, end)

const ar  = [1, 2, 3, 4, 5];

// slice from 1..3 - add 1 as the end index is not included

const ar2 = ar.slice(1, 3 + 1);

console.log(ar2);

Alex K.
la source
22
Il vaut probablement la peine de mentionner explicitement ici que l'original arn'est pas modifié. console.log(ar); // -> [1, 2, 3, 4, 5]
daemonexmachina
17

Pour une utilisation simple de slice, utilisez mon extension à Array Class:

Array.prototype.subarray = function(start, end) {
    if (!end) { end = -1; } 
    return this.slice(start, this.length + 1 - (end * -1));
};

Ensuite:

var bigArr = ["a", "b", "c", "fd", "ze"];

Test1 :

bigArr.subarray(1, -1);

<["b", "c", "fd", "ze"]

Test2:

bigArr.subarray(2, -2);

<["c", "fd"]

Test3:

bigArr.subarray(2);

<["c", "fd", "ze"]

Cela pourrait être plus facile pour les développeurs venant d'une autre langue (par exemple Groovy).

Abdennour TOUMI
la source
Ce que K_7 a dit; plus particulièrement, le patch de singe sur les Builtins (Object, Array, Promise, etc.) est très méchant. Voir le célèbre exemple de MooTools forçant un renommage du natif proposé Array.prototype.containsen Array.prototype.includes.
daemonexmachina
Sans oublier, votre subarrayméthode fournit des résultats inattendus. bigArr.slice(1,-1)renvoie ['b','c','fd'], ce à quoi vous vous attendez (le -1 fait tomber un élément de la fin du nouveau tableau). Mais bigArr.subarray(1,-1)renvoie le même que bigArr.subarray(1), c'est-à-dire tout de la position 1 à la fin de bigArr. Vous forcez également les utilisateurs à toujours donner des nombres négatifs comme endparamètre. Tout end >= -1donne le même résultat que lorsque end === undefined. D'un autre côté, les bigArr.slice(1,3)retours ['b','c'], ce qui est à nouveau attendu.
daemonexmachina
5

const array_one = [11, 22, 33, 44, 55];
const start = 1;
const end = array_one.length - 1;
const array_2 = array_one.slice(start, end);
console.log(array_2);

hannad rehman
la source
il ne compile pas ici la correction: var array_one = [11, 22, 33, 44,55]; var ar2 = array_one.slice (0, array_one.length-1); console.log (ar2)
bormat
0

La question est en fait de demander un nouveau tableau , donc je pense qu'une meilleure solution serait de combiner la réponse d'Abdennour TOUMI avec une fonction de clonage:

function clone(obj) {
  if (null == obj || "object" != typeof obj) return obj;
  const copy = obj.constructor();
  for (const attr in obj) {
    if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
  }
  return copy;
}

// With the `clone()` function, you can now do the following:

Array.prototype.subarray = function(start, end) {
  if (!end) {
    end = this.length;
  } 
  const newArray = clone(this);
  return newArray.slice(start, end);
};

// Without a copy you will lose your original array.

// **Example:**

const array = [1, 2, 3, 4, 5];
console.log(array.subarray(2)); // print the subarray [3, 4, 5, subarray: function]

console.log(array); // print the original array [1, 2, 3, 4, 5, subarray: function]

[ http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object]

user73362
la source
9
Je ne pense pas que cette tranche va changer le tableau d'origine.
Mani
10
Array.prototype.slicerenvoie déjà une copie. Array.prototype.splicemodifie le tableau d'origine.
Guido Bouman
2
La méthode slice () renvoie une copie superficielle d'une partie d'un tableau dans un nouvel objet tableau. Voir Mozilla Developer Network . Voté.
TheCrazyProgrammer
Comme d'autres l'ont dit, slicerenvoie déjà une copie superficielle, rendant cette subarrayimplémentation inutile. Mais il convient également de mentionner que vous avez patché un objet intégré avec un singe, ce qui est un gros non. Voir les commentaires sur la réponse d'Abdennour TOUMI .
daemonexmachina du