[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/array [Back]  [Original]

Arrays
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Les objets vous permettent de stocker des collections de valeurs cl. Cest trs bien.

    Mais assez souvent, nous trouvons quil nous faut une collection ordonne, o nous avons un 1er, un 2me, un 3me lment, etc. Par exemple, nous avons besoin de cela pour stocker une liste de quelque chose : utilisateurs, trucs, lments HTML, etc.

    Il nest pas pratique dutiliser un objet ici, car il ne fournit aucune mthode pour grer lordre des lments. Nous ne pouvons pas insrer une nouvelle proprit entre celles existantes. Les objets ne sont tout simplement pas destins un tel usage.

    Il existe une structure de donnes spciale appele Array (tableau), pour stocker les collections ordonnes.

    Dclaration

    Il existe deux syntaxes pour crer un tableau vide :

    let arr = new Array();
    let arr = [];

    La plupart du temps cest la deuxime syntaxe qui est utilise. Nous pouvons fournir des lments initiaux entre parenthses :

    let fruits = ["Apple", "Orange", "Plum"];

    Les lments de tableau sont numrots en commenant par zro.

    On peut obtenir un lment par son numro grace aux crochets :

    let fruits = ["Apple", "Orange", "Plum"];
    
    alert( fruits[0] ); // Apple
    alert( fruits[1] ); // Orange
    alert( fruits[2] ); // Plum

    Nous pouvons remplacer un lment :

    fruits[2] = 'Pear'; // maintenant ["Apple", "Orange", "Pear"]

    Ou en ajouter un nouveau au tableau :

    fruits[3] = 'Lemon'; // maintenant ["Apple", "Orange", "Pear", "Lemon"]

    Le nombre total dlments dans le tableau est sa length (longueur) :

    let fruits = ["Apple", "Orange", "Plum"];
    
    alert( fruits.length ); // 3

    Nous pouvons galement utiliser un alert pour afficher lensemble du tableau :

    let fruits = ["Apple", "Orange", "Plum"];
    
    alert( fruits ); // Apple,Orange,Plum

    Un tableau peut stocker des lments de tout type.

    Par exemple :

    // mlange de valeurs
    let arr = [ 'Apple', { name: 'John' }, true, function() { alert('hello'); } ];
    
    // rcupre l'objet  l'index 1 et montre ensuite son nom
    alert( arr[1].name ); // John
    
    // affiche la fonction  l'index 3 et l'excute la
    arr[3](); // hello
    Trailing comma (virgule de fin)

    Un tableau, comme pour un objet, peut se terminer par une virgule :

    let fruits = [
      "Apple",
      "Orange",
      "Plum",
    ];

    Le style virgule de fin facilite linsertion et la suppression dlments, car toutes les lignes se ressemblent.

    Rcuprer les derniers lments avec at

    Un ajout rcent
    Ceci est un ajout rcent au language. Les anciens navigateurs peuvent ncessiter des polyfills.

    Disons que nous voulons le dernier lment du tableau.

    Certains langages de programmation permettent lutilisation dindex ngatifs pour a, comme fruits[-1].

    Tandis quen JavaScript a ne fonctionnera pas. Le rsultat sera undefined, parce que lindex dans les crochets est trait littralement.

    Nous pouvons calculer explicitement lindex du dernier lment et donc y accder: fruits[fruits.length - 1].

    let fruits = ["Apple", "Orange", "Plum"];
    
    alert( fruits[fruits.length-1] ); // Plum

    Un peu lourd, nest-ce pas ? Nous devons crire le mme nom de variable deux fois.

    Heureusement, il y a une syntaxe plus courte : fruits.at(-1) :

    let fruits = ["Apple", "Orange", "Plum"];
    
    // Identique  fruits[fruits.length-1]
    alert( fruits.at(-1) ); // Plum

    En dautres termes, arr.at(i):

    • est exactement identique arr[i], si i >= 0.
    • pour les valeurs ngatives de i, a recule depuis la fin du tableau.

    Les mthodes pop/push, shift/unshift

    Une queue (file dattente) est lune des utilisations les plus courantes pour les tableaux. En informatique, cela signifie une collection ordonne dlments qui supporte deux oprations :

    • push ajoute un lment la fin.
    • shift enlve un lment depuis le dbut, en faisant avancer la file dattente, de sorte que le deuxime lment devienne le premier.
    []

    Les tableaux prennent en charge les deux oprations.

    En pratique, nous en avons besoin trs souvent. Par exemple, une file dattente de messages devant tre affichs lcran.

    Il y a un autre cas dutilisation pour les tableaux la structure de donnes nomme stack.

    Il supporte deux oprations :

    • push ajoute un lment la fin.
    • pop enlve un lment de la fin.

    Ainsi, de nouveaux lments sont ajouts ou enlevs toujours partir de la fin.

    Un stack (pile) est gnralement illustre par un jeu de cartes. De nouvelles cartes sont ajoutes ou enleves par le haut :

    []

    Pour les stacks (piles), le dernier lment envoy est reu en premier, cest le principe LIFO (Last-In-First-Out, dernier entr, premier sorti). Pour les files dattente, nous avons FIFO (First-In-First-Out, premier entr, premier sorti).

    Les tableaux en JavaScript peuvent fonctionner la fois en queue et en stack. Ils vous permettent dajouter ou supprimer des lments la fois par le dbut ou par la fin.

    En informatique, la structure de donnes qui permet cela sappelle deque.

    Mthodes qui fonctionnent avec la fin du tableau :

    pop

    Extrait le dernier lment du tableau et le renvoie :

    let fruits = ["Apple", "Orange", "Pear"];
    
    alert( fruits.pop() ); // supprime "Pear" et l'alerte
    
    alert( fruits ); // Apple, Orange

    Les deux mthodes fruits.pop() et fruits.at(-1) renvoient le dernier lment du tableau, mais fruits.pop() modifie galement le tableau en supprimant llment.

    push

    Ajoute llment la fin du tableau :

    let fruits = ["Apple", "Orange"];
    
    fruits.push("Pear");
    
    alert( fruits ); // Apple, Orange, Pear

    Lappel de fruits.push(...) est gal fruits[fruits.length] = ....

    Mthodes qui fonctionnent avec le dbut du tableau :

    shift

    Extrait le premier lment du tableau et le renvoie :

    let fruits = ["Apple", "Orange", "Pear"];
    
    alert( fruits.shift() ); // supprime "Apple" et l'alerte
    
    alert( fruits ); // Orange, Pear
    unshift

    Ajoute llment au dbut du tableau :

    let fruits = ["Orange", "Pear"];
    
    fruits.unshift("Apple");
    
    alert( fruits ); // Apple, Orange, Pear

    Les mthodes push et unshift peuvent ajouter plusieurs lments la fois :

    let fruits = ["Apple"];
    
    fruits.push("Orange", "Peach");
    fruits.unshift("Pineapple", "Lemon");
    
    // ["Pineapple", "Lemon", "Apple", "Orange", "Peach"]
    alert( fruits );

    Les internes

    Un tableau est un type dobjet spcial. Les crochets utiliss pour accder la proprit arr[0] proviennent en fait de la syntaxe de lobjet. Cest essentiellement la mme chose que obj[key], o arr est lobjet, tandis que les nombres sont utiliss comme cls.

    Ils tendent les objets en fournissant des mthodes spciales pour travailler avec des collections ordonnes de donnes ainsi que la proprit length. Mais au fond cest toujours un objet.

    Noubliez pas quil ny a que huit types de base en JavaScript (voir le chapitre Les types de donnes pour plus dinfos). Array est un objet et se comporte donc comme un objet.

    Par exemple, il est copi par rfrence :

    let fruits = ["Banana"]
    
    let arr = fruits; // copier par rfrence (deux variables font rfrence au mme tableau)
    
    alert( arr === fruits ); // true
    
    arr.push("Pear"); // modifie le tableau par rfrence
    
    alert( fruits ); // Banana, Pear - 2 items maintenant

    Mais ce qui rend les tableaux vraiment spciaux, cest leur reprsentation interne. Le moteur tente de stocker ses lments dans une zone de mmoire contigu, lun aprs lautre, exactement comme le montrent les illustrations de ce chapitre. Il existe galement dautres optimisations permettant de faire fonctionner les tableaux trs rapidement.

    Mais ils se cassent tous si nous arrtons de travailler avec un tableau comme avec une collection ordonne et commenons le travailler comme sil sagissait dun objet normal.

    Par exemple, techniquement, nous pouvons faire ceci :

    let fruits = []; // crer un tableau
    
    fruits[99999] = 5; // assigne une proprit avec un index beaucoup plus grand que sa longueur
    
    fruits.age = 25; // crer une proprit avec un nom arbitraire

    Cest possible, car les tableaux sont des objets leur base. Nous pouvons leur ajouter des proprits.

    Mais le moteur verra que nous travaillons avec le tableau comme avec un objet normal. Les optimisations spcifiques un tableau ne sont pas adaptes ce type de situation et seront dsactives. Leurs avantages disparaissent.

    Les moyens de casser un tableau :

    • Ajouter une proprit non numrique comme arr.test = 5.
    • Faire des trous, comme ajouter arr[0] et ensuite arr[1000] (et rien entre eux).
    • Remplire le tableau dans lordre inverse, comme arr[1000], arr[999] etc.

    Veuillez considrer les tableaux comme des structures spciales pour travailler avec les donnes ordones. Ils fournissent des mthodes spciales pour cela. Les tableaux sont soigneusement rgls dans les moteurs JavaScript pour fonctionner avec des donnes ordonnes contigus, veuillez les utiliser de cette manire. Et si vous avez besoin de cls arbitraires, il y a de fortes chances pour que vous ayez rellement besoin dun objet rgulier {}.

    Performance

    Les mthodes push/pop vont vite, alors que shift/unshift sont lentes.

    []

    Pourquoi est-il plus rapide de travailler avec la fin dun tableau quavec son dbut ? Voyons ce qui se passe pendant lexcution :

    fruits.shift(); // prends 1 lment du dbut

    Il ne suffit pas de prendre llment avec le nombre 0. Dautres lments doivent galement tre renumrots.

    Lopration shift doit faire 3 choses :

    1. Supprimer llment avec lindex 0.
    2. Dplacer tous les lments gauche, les renumroter de lindex 1 0, de2 1, etc.
    3. Mettre jour la proprit length.
    []

    Plus il y a dlments dans le tableau, plus il y faut de temps pour les dplacer, plus il y a doprations en mmoire.

    La mme chose se produit avec unshift. Pour ajouter un lment au dbut du tableau, nous devons dabord dplacer les lments existants vers la droite, en augmentant leur index.

    Et quen est-il avec push/pop ? Ils nont pas besoin de dplacer quoi que ce soit. Pour extraire un lment de la fin, la mthode pop nettoie lindex et raccourcit length.

    Les actions pour lopration pop :

    fruits.pop(); // enleve 1 lment de la fin
    []

    La mthode pop na pas besoin de dplacer quoi que ce soit, car les autres lments conservent leurs index. Cest pourquoi cest extrmement rapide.

    La mme chose avec la mthode push.

    Boucles

    Lune des mthodes les plus anciennes pour cycler des lments de tableau est la boucle for sur les index :

    let arr = ["Apple", "Orange", "Pear"];
    
    for (let i = 0; i < arr.length; i++) {
      alert( arr[i] );
    }

    Mais pour les tableaux, il existe une autre forme de boucle, for..of :

    let fruits = ["Apple", "Orange", "Plum"];
    
    // itre sur des lments de tableau
    for (let fruit of fruits) {
      alert( fruit );
    }

    Le for..of ne donne pas accs au numro de llment actuel, mais sa valeur, mais dans la plupart des cas, cela suffit. Et cest plus court.

    Techniquement, comme les tableaux sont des objets, il est galement possible dutiliser for..in :

    let arr = ["Apple", "Orange", "Pear"];
    
    for (let key in arr) {
      alert( arr[key] ); // Apple, Orange, Pear
    }

    Mais cest en fait une mauvaise ide. Il y a des problmes potentiels avec cela :

    1. La boucle for..in itre sur toutes les proprits, pas seulement les proprits numriques.

      Il existe des objets dits array-like dans le navigateur et dans dautres environnements, qui ressemblent des tableaux. Cest--dire quils ont les proprits length et index, mais ils peuvent galement avoir dautres proprits et mthodes non numriques, dont nous navons gnralement pas besoin. La boucle for..in les listera cependant. Donc, si nous devons travailler avec des objets de type tableau, ces proprits supplmentaires peuvent devenir un problme.

    2. La boucle for..in est optimise pour les objets gnriques, pas pour les tableaux, elle est 10-100 fois plus lente. Bien sr, cest encore trs rapide. Lacclration peut nimporter que dans les goulots dtranglement ou sembler hors de propos. Mais il faut quand mme tre conscient de la diffrence.

    En rgle gnrale, nous ne devrions pas utiliser for..in pour les tableaux.

    Un mot propos de length

    La proprit length est automatiquement mise jour lorsque nous modifions le tableau. Pour tre prcis, il ne sagit pas du nombre de valeurs du tableau, mais du plus grand index numrique plus un.

    Par exemple, un seul lment avec un grand index donne une grande longueur :

    let fruits = [];
    fruits[123] = "Apple";
    
    alert( fruits.length ); // 124

    Notez que nous nutilisons gnralement pas de tableaux de ce type.

    Une autre chose intressante propos de la proprit length est quelle est accessible en criture.

    Si nous laugmentons manuellement, rien dintressant ne se produit. Mais si nous le diminuons, le tableau est tronqu. Le processus est irrversible, voici lexemple :

    let arr = [1, 2, 3, 4, 5];
    
    arr.length = 2; // tronque  2 lments
    alert( arr ); // [1, 2]
    
    arr.length = 5; // retourne la length d'origine
    alert( arr[3] ); // undefined: les valeurs ne reviennent pas

    Ainsi, le moyen le plus simple pour effacer le tableau est arr.length = 0;.

    new Array()

    Il y a une syntaxe supplmentaire pour crer un tableau :

    let arr = new Array("Apple", "Pear", "etc");

    Il est rarement utilis, car les crochets [] sont plus courts. En outre, il comporte une caractristique dlicate.

    Si new Array est appel avec un seul argument qui est un nombre, il cre un tableau sans lments, mais avec la longueur donne.

    Voyons comment on peut se tirer une balle dans le pied :

    let arr = new Array(2); // va-t-il crer un tableau de [2] ?
    
    alert( arr[0] ); // undefined! pas d'lments.
    
    alert( arr.length ); // length 2

    Pour viter de telles surprises, nous utilisons gnralement des crochets, sauf si nous savons vraiment ce que nous faisons.

    Tableaux multidimensionnels

    Les tableaux peuvent avoir des lments qui sont aussi des tableaux. On peut lutiliser pour des tableaux multidimensionnels, pour stocker des matrices :

    let matrix = [
      [1, 2, 3],
      [4, 5, 6],
      [7, 8, 9]
    ];
    
    alert( matrix[1][1] ); // 5, l'lment central

    toString

    Les tableaux ont leur propre implmentation de la mthode toString qui renvoie une liste dlments spars par des virgules.

    Par exemple :

    let arr = [1, 2, 3];
    
    alert( arr ); // 1,2,3
    alert( String(arr) === '1,2,3' ); // true

    Aussi, essayons ceci :

    alert( [] + 1 ); // "1"
    alert( [1] + 1 ); // "11"
    alert( [1,2] + 1 ); // "1,21"

    Les tableaux nont pas de Symbol.toPrimitive, ni de valueOf viable, ils implmentent uniquement la conversion toString, donc ici [] devient une chane vide, [1] devient "1" et [1,2] devient "1,2".

    Lorsque loprateur binaire plus + ajoute quelque chose une chane, il la convertit galement en chane, de sorte que ltape suivante se prsente comme suit :

    alert( "" + 1 ); // "1"
    alert( "1" + 1 ); // "11"
    alert( "1,2" + 1 ); // "1,21"

    Ne comparez pas les tableaux avec ==

    Les tableaux en JavaScript, contrairement certains autres langages de programmation, ne doivent pas tre compars avec loprateur ==.

    Cet oprateur na pas de traitement spcial pour les tableaux, il fonctionne avec eux comme avec nimporte quel objet.

    Rappelons les rgles :

    • Deux objets sont gaux == uniquement sils font rfrence au mme objet.
    • Si lun des arguments de == est un objet, et lautre est une primitive, alors lobjet est converti en primitif, comme expliqu dans le chapitre Conversion d'objet en primitive.
    • lexception de null et undefined qui sgalent == lun lautre et rien dautre.

    La comparaison stricte === est encore plus simple, car elle ne convertit pas les types.

    Donc, si nous comparons des tableaux avec ==, ils ne sont jamais les mmes, sauf si nous comparons deux variables qui rfrencent exactement le mme tableau.

    Par exemple :

    alert( [] == [] ); // false
    alert( [0] == [0] ); // false

    Ces tableaux sont des objets techniquement diffrents. Donc, ils ne sont pas gaux. Loprateur == ne fait pas de comparaison lment par lment.

    La comparaison avec les primitives peut galement donner des rsultats apparemment tranges :

    alert( 0 == [] ); // true
    
    alert('0' == [] ); // false

    Ici, dans les deux cas, nous comparons une primitive un objet tableau. Ainsi, le tableau [] est converti en primitive des fins de comparaison et devient une chane vide ''.

    Ensuite, le processus de comparaison se poursuit avec les primitives, comme dcrit dans le chapitre Les conversions de types :

    // aprs que [] soit converti vers ''
    alert( 0 == '' ); // true, car '' est converti en nombre 0
    
    alert('0' == '' ); // false, pas de conversion de type, diffrentes chanes de caractres

    Alors, comment comparer des tableaux ?

    Cest simple, nutilisez pas loprateur ==. Au lieu de cela, comparez-les lment par lment dans une boucle ou en utilisant les mthodes ditration expliques dans le chapitre suivant.

    Rsum

    Array est un type dobjet spcial, adapt au stockage et la gestion des lments de donnes ordonnes.

    • La dclaration :

      // crochets (habituel)
      let arr = [item1, item2...];
      
      // new Array (exceptionnellement rare)
      let arr = new Array(item1, item2...);

      Lappel de new Array(number) cre un tableau de longueur donne, mais sans lments.

    • La proprit length est la longueur du tableau ou, plus prcisment, son dernier index numrique plus un. Il est auto-ajust par les mthodes de tableau.

    • Si nous raccourcissons length manuellement, le tableau est tronqu.

    Obtenir les lments:

    • nous pouvons obtenir un lment par son index, comme arr[0]
    • nous pouvons galement utiliser la mthode at(i) qui autorise les index ngatifs. Pour les valeurs ngatives de i, il recule partir de la fin du tableau. Si i >= 0, cela fonctionne comme arr[i].

    Nous pouvons utiliser un tableau comme deque avec les oprations suivantes:

    • push(...items) ajoute items la fin.
    • pop() supprime llment de la fin et le renvoie.
    • shift() supprime llment du dbut et le renvoie.
    • unshift(... items) ajoute des items au dbut.

    Pour boucler sur les lments du tableau :

    • for (let i = 0; i <arr.length; i++) fonctionne le plus rapidement, compatible avec les anciens navigateurs.
    • for (let item of arr) la syntaxe moderne pour les lments uniquement.
    • pour (let i in arr) ne jamais utiliser.

    Pour comparer des tableaux, nutilisez pas loprateur == (ainsi que >, < et autres), car ils nont pas de traitement spcial pour les tableaux. Ils les traitent comme nimporte quel objet, et ce nest pas ce que nous voulons habituellement.

    A la place, vous pouvez utiliser la boucle for..of pour comparer les tableaux lment par lment.

    Nous continuerons avec les tableaux et tudierons dautres mthodes pour ajouter, supprimer, extraire des lments et trier des tableaux dans le prochain chapitre Mthodes de tableau.

    Exercices

    importance: 3

    Quest-ce que ce code va montrer ?

    let fruits = ["Apples", "Pear", "Orange"];
    
    // pousser une nouvelle valeur dans la "copie"
    let shoppingCart = fruits;
    shoppingCart.push("Banana");
    
    // Qu'y a-t-il dans fruits ?
    alert( fruits.length ); // ?
    solution

    Le rsultat est 4 :

    let fruits = ["Apples", "Pear", "Orange"];
    
    let shoppingCart = fruits;
    
    shoppingCart.push("Banana");
    
    alert( fruits.length ); // 4

    Cest parce que les tableaux sont des objets. Donc, shoppingCart et fruits sont les rfrences du mme tableau.

    importance: 5

    Essayons 5 oprations de tableau.

    1. Crez un tableau styles avec les lments Jazz et Blues.
    2. Ajoutez Rock-n-Roll la fin.
    3. Remplacez la valeur au milieu par Classiques. Votre code pour trouver la valeur moyenne devrait fonctionner pour tous les tableaux de longueur impaire.
    4. Extrayez la premire valeur du tableau et affichez-la.
    5. Ajoutez Rap et Reggae au tableau.

    Le processus du tableau :

    Jazz, Blues
    Jazz, Blues, Rock-n-Roll
    Jazz, Classics, Rock-n-Roll
    Classics, Rock-n-Roll
    Rap, Reggae, Classics, Rock-n-Roll
    solution
    let styles = ["Jazz", "Blues"];
    styles.push("Rock-n-Roll");
    styles[Math.floor((styles.length - 1) / 2)] = "Classics";
    alert( styles.shift() );
    styles.unshift("Rap", "Reggae");
    importance: 5

    Quel est le rsultat ? Et pourquoi ?

    let arr = ["a", "b"];
    
    arr.push(function() {
      alert( this );
    });
    
    arr[2](); // ?
    solution

    Lappel de arr[2]() est syntaxiquement le bon vieux obj[method](), dans le rle de obj on a arr, et dans le rle de method on a 2.

    Nous avons donc un appel de la fonction arr[2] comme mthode dobjet. Naturellement, il reoit this en rfrenant lobjet arr et sort le tableau :

    let arr = ["a", "b"];
    
    arr.push(function() {
      alert( this );
    })
    
    arr[2](); // a,b,function(){...}

    Le tableau a 3 valeurs. Il en avait initialement deux, plus la fonction.

    importance: 4

    crivez la fonction sumInput() qui :

    • Demande lutilisateur des valeurs utilisant prompt et stocke les valeurs dans le tableau.
    • Finit de demander lorsque lutilisateur entre une valeur non numrique, une chane vide ou appuie sur Annuler.
    • Calcule et retourne la somme des lments du tableau.

    P.S. Un zro 0 est un nombre valide, donc sil vous plat narrtez pas lentre sur zro.

    Excuter la dmo

    solution

    Veuillez noter le dtail subtile mais important de la solution. Nous ne convertissons pas instantanment value en nombre aprs le prompt, parce quaprs value = +value nous ne pourrions pas distinguer une chane vide (signe darrt) du zro (nombre valide). Nous le faisons plus tard la place.

    function sumInput() {
    
      let numbers = [];
    
      while (true) {
    
        let value = prompt("A number please?", 0);
    
        // devrions-nous annuler ?
        if (value === "" || value === null || !isFinite(value)) break;
    
        numbers.push(+value);
      }
    
      let sum = 0;
      for (let number of numbers) {
        sum += number;
      }
      return sum;
    }
    
    alert( sumInput() );
    importance: 2

    Lentre est un tableau de nombres, par exemple arr = [1, -2, 3, 4, -9, 6].

    La tche est la suivante : trouver le sous-tableau contigu de arr avec la somme maximale des items.

    crire la fonction getMaxSubSum(arr) qui retournera cette somme.

    Par exemple :

    getMaxSubSum([-1, 2, 3, -9]) == 5 (la somme des lments en surbrillance)
    getMaxSubSum([2, -1, 2, 3, -9]) == 6
    getMaxSubSum([-1, 2, 3, -9, 11]) == 11
    getMaxSubSum([-2, -1, 1, 2]) == 3
    getMaxSubSum([100, -9, 2, -3, 5]) == 100
    getMaxSubSum([1, 2, 3]) == 6 (prend tout)

    Si tous les lments sont ngatifs, cela signifie que nous nen prenons aucun (le sous-tableau est vide), la somme est donc zro :

    getMaxSubSum([-1, -2, -3]) = 0

    Sil vous plat essayez de penser une solution rapide : O(n2) ou mme O(n) si vous le pouvez.

    Open a sandbox with tests.

    solution
    Solution lente

    Solution lente

    Nous pouvons calculer tous les subsums possibles.

    Le moyen le plus simple consiste prendre chaque lment et calculer les sommes de tous les sous-tableaux partir de celui-ci.

    Par exemple, pour [-1, 2, 3, -9, 11] :

    // Commence  -1 :
    -1
    -1 + 2
    -1 + 2 + 3
    -1 + 2 + 3 + (-9)
    -1 + 2 + 3 + (-9) + 11
    
    // Commence  2 :
    2
    2 + 3
    2 + 3 + (-9)
    2 + 3 + (-9) + 11
    
    // Commence  3 :
    3
    3 + (-9)
    3 + (-9) + 11
    
    // Commence  -9 :
    -9
    -9 + 11
    
    // Commence  11 :
    11

    Le code est en ralit une boucle imbrique : la boucle externe recouvrant les lments du tableau, et linterne compte les sous-sommes commenant par llment en cours.

    function getMaxSubSum(arr) {
      let maxSum = 0; // si on ne prend aucun lment, zro sera retourn
    
      for (let i = 0; i < arr.length; i++) {
        let sumFixedStart = 0;
        for (let j = i; j < arr.length; j++) {
          sumFixedStart += arr[j];
          maxSum = Math.max(maxSum, sumFixedStart);
        }
      }
    
      return maxSum;
    }
    
    alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
    alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
    alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
    alert( getMaxSubSum([1, 2, 3]) ); // 6
    alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100

    La solution a une complexit temporelle de O(n2). En dautres termes, si nous augmentons la taille du tableau 2 fois, lalgorithme fonctionnera 4 fois plus longtemps.

    Pour les grands tableaux (1000, 10000 lments ou plus), de tels algorithmes peuvent conduire une grande lenteur.

    Solution rapide

    Solution rapide

    Parcourons le tableau et conservons la somme partielle actuelle des lments dans la variable s. Si s devient ngatif un moment donn, assignez s=0. Le maximum de tous ces s sera la rponse.

    Si la description est trop vague, veuillez voir le code, il est assez court :

    function getMaxSubSum(arr) {
      let maxSum = 0;
      let partialSum = 0;
    
      for (let item of arr) { // pour chaque lment d'arr
        partialSum += item; // l'ajouter  partialSum
        maxSum = Math.max(maxSum, partialSum); // mmorise le maximum
        if (partialSum < 0) partialSum = 0; // zro si ngatif
      }
    
      return maxSum;
    }
    
    alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
    alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
    alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
    alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
    alert( getMaxSubSum([1, 2, 3]) ); // 6
    alert( getMaxSubSum([-1, -2, -3]) ); // 0

    Lalgorithme ncessite exactement 1 passage de tableau, la complexit temporelle est donc O(n).

    Vous pouvez trouver plus dinformations dtailles sur lalgorithme ici : Maximum subarray problem. Si la raison de ce fonctionnement nest pas encore vidente, tracez lalgorithme partir des exemples ci-dessus et voyez comment il fonctionne.

    Ouvrez la solution avec des tests dans une sandbox.

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page