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

Arrays (rkker)
DA

Vi nsker at gre dette open source-projekt tilgngeligt for folk over hele verden.

Hjlp med at overstte indholdet af denne tutorial til dit sprog!

    Sg p Javascript.info:
    Sg i tutorialen:
    Lyst temaMrkt tema
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Arrays (rkker)

    Objekter tillader dig at gemme samlinger af vrdier med ngler. Det er fint.

    Men meget ofte finder vi ud af, at vi har brug for en ordnet samling, hvor vi har et 1., et 2., et 3. element osv. For eksempel har vi brug for det til at gemme en liste over noget: brugere, varer, HTML-elementer osv.

    Det er ikke praktisk at bruge et objekt her, fordi det ikke giver metoder til at hndtere rkkeflgen af elementer. Vi kan ikke indstte en ny egenskab mellem de eksisterende. Objekter er bare ikke beregnet til sdan brug.

    Der findes en speciel datastruktur kaldet Array, til at gemme ordnede samlinger.

    Deklaration

    Der er to syntakser til at oprette et tomt array:

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

    Nsten altid bruges den anden syntaks. Vi kan angive startvrdier i parenteserne:

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

    Array elementer er nummererede, startende fra nul.

    Vi kan f et element ved dets nummer i firkantede parenteser:

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits[0] ); // ble
    alert( fruits[1] ); // Appelsin
    alert( fruits[2] ); // Blomme

    Vi kan erstatte et element:

    fruits[2] = 'Pre'; // now ["ble", "Appelsin", "Pre"]

    Eller tilfj en ny til arrayet:

    fruits[3] = 'Citron'; // now ["ble", "Appelsin", "Pre", "Citron"]

    Det samlede antal elementer i arrayet er dets length:

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits.length ); // 3

    Vi kan ogs bruge alert til at vise hele arrayet.

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits ); // ble,Appelsin,Blomme

    Et array kan gemme elementer af enhver type.

    For eksempel, det kan vre en blanding af vrdier:

    // blanding af vrdier
    let arr = [ 'ble', { name: 'Karsten' }, true, function() { alert('hej'); } ];
    
    // henter objektet ved indeks 1 og viser dets navn
    alert( arr[1].name ); // Karsten
    
    // henter funktionen ved indeks 3 og krer den
    arr[3](); // hej
    Hngende komma

    Et array, ligesom et objekt, kan ende med et komma:

    let fruits = [
      "ble",
      "Appelsin",
      "Blomme",
    ];

    Det hngende komma gr det lettere at indstte/fjerne elementer, fordi alle linjer bliver ens.

    Hente sidste elementer med at

    En nylig tilfjelse
    Dette er en nylig tilfjelse til sproget. ldre browsere kan have brug for polyfills.

    Lad os sige, at vi vil have det sidste element i arrayet.

    Nogle programmeringssprog tillader brugen af negative indekser til det samme forml, som fruits[-1].

    Men i JavaScript virker det ikke. Resultatet vil vre undefined, fordi indekset i firkantede parenteser behandles bogstaveligt.

    Vi kan eksplicit beregne indekset for det sidste element og derefter f adgang til det: fruits[fruits.length - 1].

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits[fruits.length-1] ); // Blomme

    En smule besvrligt, ikke? Vi skal skrive variabelnavnet to gange.

    Heldigvis findes der en kortere syntaks: fruits.at(-1):

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    // Samme som fruits[fruits.length-1]
    alert( fruits.at(-1) ); // Blomme

    Med andre ord, arr.at(i):

    • er prcis det samme som arr[i], hvis i >= 0.
    • for negative vrdier af i, gr det baglns fra slutningen af arrayet.

    Metoderne pop/push, shift/unshift

    En k er en af de mest almindelige anvendelser af et array. I datalogi betyder det en ordnet samling af elementer, som understtter to operationer:

    • push tilfjer et element til slutningen.
    • shift henter et element fra begyndelsen, hvilket flytter ken frem, s det 2. element bliver det 1.
    []

    Arrays understtter begge operationer.

    I praksis har vi ofte brug for det. For eksempel en k af beskeder, der skal vises p skrmen.

    Der er en anden anvendelse af arrays datastrukturen kaldet stak.

    Den understtter to operationer:

    • push tilfjer et element til slutningen.
    • pop henter et element fra slutningen.

    S nye elementer tilfjes eller tages altid fra enden.

    En stak illustreres normalt som en bunke kort: nye kort tilfjes verst eller tages fra verst:

    []

    For stakke modtages det senest tilfjede element frst, det kaldes ogs LIFO-princippet (Last-In-First-Out). For ker har vi FIFO (First-In-First-Out).

    Arrays i JavaScript kan fungere bde som en k og som en stak. De tillader dig at tilfje/fjerne elementer bde i starten og i slutningen. I datalogi kaldes datastrukturen, der tillader dette, for en deque.

    Metoder, der arbejder med slutningen af arrayet:

    pop

    Trkker det sidste element ud af arrayet og returnerer det:

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits.pop() ); // fjern "Blomme" og vis det
    
    alert( fruits ); // ble, Appelsin

    Bde fruits.pop() og fruits.at(-1) returnerer det sidste element i arrayet, men fruits.pop() ndrer ogs arrayet ved at fjerne det.

    push

    Tilfjer elementet til slutningen af arrayet:

    let fruits = ["ble", "Appelsin"];
    
    fruits.push("Blomme");
    
    alert( fruits ); // ble, Appelsin, Blomme

    Kaldet fruits.push(...) svarer til fruits[fruits.length] = ....

    Metoder, der arbejder med begyndelsen af arrayet:

    shift

    Trkker det frste element ud af arrayet og returnerer det:

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    alert( fruits.shift() ); // fjern "ble" og vis det
    
    alert( fruits ); // Appelsin, Blomme
    unshift

    Tilfjer elementet til begyndelsen af arrayet:

    let fruits = ["Appelsin", "Blomme"];
    
    fruits.unshift('ble');
    
    alert( fruits ); // ble, Appelsin, Blomme

    Metoderne push og unshift kan tilfje flere elementer p n gang:

    let fruits = ["ble"];
    
    fruits.push("Appelsin", "Blomme");
    fruits.unshift("Ananas", "Citron");
    
    // ["Ananas", "Citron", "ble", "Appelsin", "Blomme"]
    alert( fruits );

    Intern opbygning

    Et array er en srlig slags objekt. De firkantede parenteser, der bruges til at f adgang til en egenskab arr[0], stammer faktisk fra objektsyntaksen. Det er i bund og grund det samme som obj[key], hvor arr er objektet, mens tal bruges som ngler.

    De udvider objekter ved at tilbyde specielle metoder til at arbejde med ordnede samlinger af data og ogs length-egenskaben. Men i kernen er det stadig et objekt.

    Husk, der kun er otte grundlggende datatyper i JavaScript (se kapitlet Datatyper for mere info). Array er et objekt og opfrer sig derfor som et objekt.

    For eksempel kopieres det ved reference:

    let fruits = ["Banan"]
    
    let arr = fruits; // kopier ved reference (to variabler refererer til samme array)
    
    alert( arr === fruits ); // true
    
    arr.push("Pre"); // ndrer arrayet ved reference
    
    alert( fruits ); // Banan, Pre - 2 elementer nu

    Men det, der virkelig gr arrays specielle, er deres interne reprsentation. Motoren forsger at gemme elementerne i et sammenhngende hukommelsesomrde, t efter t, som vist p illustrationerne i dette kapitel, og der er ogs andre optimeringer for at f arrays til at kre virkelig hurtigt.

    Men de bryder alle sammen, hvis vi holder op med at arbejde med et array som en ordnet samling og begynder at arbejde med det, som om det var et almindeligt objekt.

    For eksempel kan vi teknisk set gre dette:

    let fruits = []; // lav et array
    
    fruits[99999] = 5; // tildel en egenskab med et indeks langt strre end lngden
    
    fruits.age = 25; // opret en egenskab med et vilkrligt navn

    Det er muligt, fordi arrays i bund og grund er objekter. Vi kan tilfje vilkrlige egenskaber til dem.

    Men motoren vil se, at vi arbejder med arrayet som med et almindeligt objekt. Array-specifikke optimeringer er ikke egnede til sdanne tilflde og vil blive slet fra, deres fordele forsvinder.

    Mder at misbruge et array p:

    • Tilfj en ikke-numerisk egenskab som arr.test = 5.
    • Lav huller, som: tilfj arr[0] og derefter arr[1000] (og intet imellem).
    • Fyld arrayet i omvendt rkkeflge, som arr[1000], arr[999] og s videre.

    Tnk venligst p arrays som specielle strukturer til at arbejde med ordnede data. De tilbyder specielle metoder til det. Arrays er omhyggeligt optimeret i JavaScript-motorer til at arbejde med sammenhngende ordnede data, brug dem venligst p denne mde. Og hvis du har brug for vilkrlige ngler, er chancerne store for, at du faktisk har brug for et almindeligt objekt {}.

    Performance

    Metoderne push/pop krer hurtigt, mens shift/unshift er langsomme.

    []

    Hvorfor er det hurtigere at arbejde med enden af et array end med begyndelsen? Lad os se, hvad der sker under udfrelsen:

    fruits.shift(); // fjern 1 element fra starten

    Det er ikke nok at tage og fjerne elementet med indekset 0. De andre elementer skal ogs omnummereres.

    shift-operationen skal gre 3 ting:

    1. Fjern elementet med indekset 0.
    2. Flyt alle elementer til venstre, omnummerer dem fra indekset 1 til 0, fra 2 til 1 og s videre.
    3. Opdater length-egenskaben.
    []

    Jo flere elementer i arrayet, jo lngere tid tager det at flytte dem, flere operationer i hukommelsen.

    Det samme sker med unshift: for at tilfje et element i begyndelsen af arrayet, skal vi frst flytte eksisterende elementer til hjre, hvilket ger deres indekser.

    Og hvad med push/pop? De behver ikke at flytte noget. For at fjerne et element fra enden, rydder pop-metoden indekset og forkorter length.

    Handlingerne for pop-operationen:

    fruits.pop(); // fjern 1 element fra enden
    []

    pop-metoden behver ikke at flytte noget, fordi de andre elementer beholder deres indekser. Derfor er den lynhurtig.

    Det samme glder for push-metoden.

    Lkker

    En af de traditionelle mder at gennemlbe array-elementer p er ved at bruge for-loopet over indekser:

    let arr = ["ble", "Appelsin", "Pre"];
    
    for (let i = 0; i < arr.length; i++) {
      alert( arr[i] );
    }

    Men for arrays er der en anden form for lkke, for..of:

    let fruits = ["ble", "Appelsin", "Blomme"];
    
    // itererer over array-elementer
    for (let fruit of fruits) {
      alert( fruit );
    }

    for..of giver ikke adgang til nummeret p det aktuelle element, kun dets vrdi, men i de fleste tilflde er det nok. Og det er kortere.

    Teknisk set, fordi arrays er objekter, er det ogs muligt at bruge for..in:

    let arr = ["ble", "Appelsin", "Pre"];
    
    for (let key in arr) {
      alert( arr[key] ); // ble, Appelsin, Pre
    }

    Men det er faktisk en drlig id. Der er potentielle problemer med det:

    1. Lkken for..in itererer over alle egenskaber, ikke kun de numeriske.

      Der findes skaldte array-lignende objekter i browseren og i andre miljer, som ligner arrays. Det vil sige, de har length og indeks-egenskaber, men de kan ogs have andre ikke-numeriske egenskaber og metoder, som vi normalt ikke har brug for. for..in-lkken vil dog liste dem. S hvis vi skal arbejde med array-lignende objekter, kan disse ekstra egenskaber blive et problem.

    2. for..in-lkken er optimeret til generiske objekter, ikke arrays, og derfor er den 10-100 gange langsommere. Selvflgelig er den stadig meget hurtig. Hastighedsfordelen kan kun vre relevant i flaskehalse. Men vi br stadig vre opmrksomme p forskellen.

    Generelt br vi ikke bruge for..in til arrays.

    Lidt detaljer om length

    length-egenskaben opdateres automatisk, nr vi ndrer arrayet. For at vre prcis, er det faktisk ikke antallet af vrdier i arrayet, men den strste numeriske indeks plus n.

    For eksempel, et enkelt element med en stor indeks giver en stor lngde:

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

    Bemrk, at vi normalt ikke bruger arrays p den mde.

    En anden interessant ting ved length-egenskaben er, at den kan skrives til.

    Hvis vi ger den manuelt, sker der ikke noget interessant. Men hvis vi mindsker den, bliver arrayet forkortet. Processen er irreversibel, her er et eksempel:

    let arr = [1, 2, 3, 4, 5];
    
    arr.length = 2; // forkort til 2 elementer
    alert( arr ); // [1, 2]
    
    arr.length = 5; // returner lngden tilbage
    alert( arr[3] ); // undefined: vrdierne kommer ikke tilbage

    S den enkleste mde at rydde arrayet p er: arr.length = 0;.

    new Array()

    Der er endnu en syntaks til at oprette et array:

    let arr = new Array("ble", "Pre", "osv");

    Det bruges sjldent, fordi firkantede parenteser [] er kortere. Derudover er der en tricky funktion med det.

    Hvis new Array kaldes med et enkelt argument, som er et tal, s opretter det et array uden elementer, men med den givne lngde.

    Lad os se hvordan man kan skyde sig selv i foden ved at bruge new Array:

    let arr = new Array(2); // vil det oprette et array med [2] ?
    
    alert( arr[0] ); // undefined! intet element.
    
    alert( arr.length ); // length 2

    For at undg sdanne overraskelser bruger vi normalt firkantede parenteser, medmindre vi virkelig ved, hvad vi gr.

    Flerdimensionale arrays

    Arrays kan have elementer, som ogs er arrays. Vi kan bruge det til flerdimensionale arrays, for eksempel til at gemme matricer eller tabeller.:

    let matrix = [
      [1, 2, 3],
      [4, 5, 6],
      [7, 8, 9]
    ];
    
    alert( matrix[0][1] ); // 2, den anden vrdi i det frste indre array

    toString

    Arrays har deres egen implementering af toString-metoden, som returnerer en kommasepareret liste over elementer.

    For eksempel, her er et array med tre elementer:

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

    Lad os ogs prve dette:

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

    Arrays har ikke Symbol.toPrimitive, heller ikke en brugbar valueOf, de implementerer kun toString-konvertering, s her bliver [] til en tom streng, [1] bliver "1" og [1,2] bliver "1,2".

    Nr den binre plus "+" operator lgger noget til en streng, konverterer den det ogs til en streng, s nste trin ser sdan ud:

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

    Sammenlign ikke arrays med ==

    Arrays i JavaScript, i modstning til nogle andre programmeringssprog, br ikke sammenlignes med operatoren ==.

    Denne operator har ingen srlig behandling for arrays, den fungerer med dem som med enhver anden objekt.

    Lad os genopfriske reglerne:

    • To objekter er lige == kun hvis de refererer til det samme objekt.
    • Hvis et af argumenterne til == er et objekt, og det andet er en primitiv, s bliver objektet konverteret til en primitiv, som forklaret i kapitlet Konvertering fra objekt til primitiv.
    • Med undtagelse af null og undefined, som er lige == hinanden og intet andet.

    Streng sammenligning === er endnu enklere, da den ikke konverterer typer.

    S hvis vi sammenligner arrays med ==, er de aldrig ens, medmindre vi sammenligner to variabler, der refererer til prcis det samme array.

    For eksempel:

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

    Disse arrays er teknisk set forskellige objekter. S de er ikke ens. Operatoren == laver ikke element-for-element sammenligning.

    Sammenligning med primitivtyper kan ogs give tilsyneladende mrkelige resultater:

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

    I begge tilflde sammenligner vi en primitiv med et array-objekt. S arrayet [] bliver konverteret til en primitiv med henblik p sammenligning og bliver til en tom streng ''.

    Sammenligningsprocessen fortstter derefter med primitivtyperne, som beskrevet i kapitlet Konvertering mellem datatyper:

    // efter [] blev konverteret til ''
    alert( 0 == '' ); // true, da '' bliver konverteret til tallet 0
    
    alert('0' == '' ); // false, ingen typekonvertering, forskellige strenge

    S, hvordan sammenligner man arrays?

    Det er egentlig simpelt: brug ikke == operatoren. Sammenlign dem i stedet element-for-element i en lkke eller ved hjlp af iterationsmetoder, der forklares i det nste kapitel.

    Opsummering

    Array er en speciel slags objekt, velegnet til at gemme og hndtere ordnede dataelementer.

    Deklarationen:

    // firkantede parenteser (almindeligt)
    
    let arr = [item1, item2...];
    
    // new Array (meget sjldent)
    let arr = new Array(item1, item2...);

    Kaldet til new Array(number) opretter et array med den givne lngde, men uden elementer.

    • length-egenskaben er arrayets lngde eller, mere prcist, dets sidste numeriske indeks plus en. Den justeres automatisk af array-metoder.
    • Hvis vi forkorter length manuelt, bliver arrayet forkortet.

    Hentning af elementer:

    • vi kan f elementet ved dets indeks, som arr[0]
    • vi kan ogs bruge metoden at(i), som tillader negative indekser. For negative vrdier af i tller den baglns fra slutningen af arrayet. Hvis i >= 0, fungerer den som arr[i].

    Vi kan bruge et array som en deque med flgende operationer:

    • push(...items) tilfjer items til slutningen.
    • pop() fjerner elementet fra slutningen og returnerer det.
    • shift() fjerner elementet fra begyndelsen og returnerer det.
    • unshift(...items) tilfjer items til begyndelsen.

    For at gennemlbe elementerne i arrayet, kan vi bruge en af flgende lkker:

    • for (let i=0; i<arr.length; i++) virker hurtigst, kompatibel med gamle browsere.
    • for (let item of arr) den moderne syntaks for kun elementer,
    • for (let i in arr) brug aldrig.

    For at sammenligne arrays, brug ikke == operatoren (eller >, < og andre), da de ikke har nogen srlig behandling for arrays. De hndterer dem som almindelige objekter, og det er ikke, hvad vi normalt nsker.

    I stedet kan du bruge en for..of lkke til at sammenligne arrays element-for-element.

    Vi fortstter med arrays og studerer flere metoder til at tilfje, fjerne, udtrkke elementer og sortere arrays i det nste kapitel Array-metoder.

    Opgaver

    vigtighed: 3

    Hvad vil denne kode vise?

    let fruits = ["ble", "Pre", "Appelsin"];
    
    // skub push en ny vrdi ind i "kopien"
    let shoppingCart = fruits;
    shoppingCart.push("Banan");
    
    // hvad er der i fruits?
    alert( fruits.length ); // ?
    lsning

    Resultatet er 4:

    let fruits = ["ble", "Pre", "Appelsin"];
    
    let shoppingCart = fruits;
    
    shoppingCart.push("Banan");
    
    alert( fruits.length ); // 4
    ``` Det er fordi arrays er objekter. S bde `shoppingCart` og `fruits` er referencer til det samme array.
    vigtighed: 5

    Lad os prve 5 array operationer.

    1. Opret et array styles med elementerne Jazz og Blues.
    2. Tilfj Rock-n-Roll til slutningen.
    3. Erstat vrdien i midten med Classics. Din kode til at finde midtervrdien skal fungere for alle arrays med ulige lngde.
    4. Fjern den frste vrdi i arrayet og vis den.
    5. Tilfj Rap og Reggae til begyndelsen af arrayet.

    Arrayet i processen skal se sdan ud:

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

    Hvad er resultatet? Hvorfor?

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

    Kaldet arr[2]() er syntaktisk den gode gamle obj[method](), hvor arr spiller rollen som obj, og 2 spiller rollen som method.

    S vi har et kald af funktionen arr[2] som en objektmetode. Naturligvis modtager den this, der refererer til objektet arr og udskriver arrayet:

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

    Arrayet har 3 vrdier: oprindeligt havde det to, plus funktionen. Nr vi kalder arr[2](), s er this i funktionen lig med arr, og det udskrives som a,b,function(){}.

    vigtighed: 4

    Skriv en funktion sumInput() som:

    • Sprger brugeren om vrdier med prompt og gemmer vrdierne i et array.
    • Stopper med at sprge, nr brugeren indtaster en ikke-numerisk vrdi, en tom streng eller trykker Annuller.
    • Beregner og returnerer summen af arrayets elementer.

    P.S. Et nul 0 er et gyldigt tal, s stop ikke inputtet ved nul.

    Kr demoen

    lsning

    Bemrk den subtile, men vigtige detalje i lsningen. Vi konverterer ikke value til et tal med det samme efter prompt, fordi efter value = +value ville vi ikke kunne skelne en tom streng (stoptegn) fra nul (gyldigt tal). Vi gr det senere i stedet.

    function sumInput() {
    
      let numbers = [];
    
      while (true) {
    
        let value = prompt("Indtast et tal?", 0);
    
        // skal vi afbryde?
        if (value === "" || value === null || !isFinite(value)) break;
    
        numbers.push(+value);
      }
    
      let sum = 0;
      for (let number of numbers) {
        sum += number;
      }
      return sum;
    }
    
    alert( sumInput() );
    vigtighed: 2

    Input er et array af tal, f.eks. arr = [1, -2, 3, 4, -9, 6].

    Opgaven er: find det sammenhngende delarray af arr med den maksimale sum af elementer.

    Skriv funktionen getMaxSubSum(arr), der returnerer den sum.

    For eksempel:

    getMaxSubSum([-1, 2, 3, -9]) == 5 (summen af de markerede elementer)
    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 (tag det hele)

    Hvis alle elementer er negative, betyder det, at vi ikke tager nogen (delarrayet er tomt), s summen er nul:

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

    Prv at tnke p en hurtig lsning: O(n2) eller endda O(n), hvis du kan.

    bn en sandbox med tests.

    lsning
    Langsom lsning

    Langsom lsning

    Vi kan beregne alle mulige delsummer.

    Den simpleste mde er at tage hvert element og beregne summen af alle delarrays, der starter fra det. For eksempel, for [-1, 2, 3, -9, 11]:

    // Startende fra -1:
    -1
    -1 + 2
    -1 + 2 + 3
    -1 + 2 + 3 + (-9)
    -1 + 2 + 3 + (-9) + 11
    
    // Startende fra 2:
    2
    2 + 3
    2 + 3 + (-9)
    2 + 3 + (-9) + 11
    
    // Startende fra 3:
    3
    3 + (-9)
    3 + (-9) + 11
    
    // Startende fra -9
    -9
    -9 + 11
    
    // Startende fra 11
    11

    Koden er faktisk en indlejret lkke: den ydre lkke gr over array-elementerne, og den indre tller delsummer, der starter med det aktuelle element.

    function getMaxSubSum(arr) {
      let maxSum = 0; // hvis vi ikke tager nogle elementer, vil nul blive returneret
    
      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

    Lsningen har en tidskompleksitet p O(n2). Med andre ord, hvis vi fordobler strrelsen p arrayet, vil algoritmen tage fire gange s lang tid.

    For store arrays (1000, 10000 eller flere elementer) kan sdanne algoritmer fre til alvorlig langsommelighed.

    Hurtig lsning

    Hurtig lsning

    Lad os g igennem arrayet og holde den nuvrende delsum af elementer i variablen s. Hvis s bliver negativ p et tidspunkt, s st s=0. Maksimum af alle sdanne s vil vre svaret.

    Hvis beskrivelsen er for vag, s se venligst koden, den er kort nok:

    function getMaxSubSum(arr) {
      let maxSum = 0;
      let partialSum = 0;
    
      for (let item of arr) { // for hvert item af arr
        partialSum += item; // lg item til partialSum
        maxSum = Math.max(maxSum, partialSum); // husk maksimum
        if (partialSum < 0) partialSum = 0; // nul hvis negativ
      }
    
      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

    Algoritmen krver prcis 1 gennemgang af arrayet, s tidskompleksiteten er O(n).

    Du kan finde mere detaljeret information om algoritmen her: Maximum subarray problem. Hvis det stadig ikke er indlysende, hvorfor det virker, s prv at flge algoritmen p eksemplerne ovenfor, se hvordan den fungerer, det er ofte bedre end ord.

    bn lsningen med tests i en sandbox.

    Tutorial-oversigt

    Kommentarer

    ls dette fr du kommenterer
    • Hvis du har forslag til forbedringer - s opret venligst et GitHub-issue eller en pull request i stedet for at kommentere.
    • Hvis du ikke forstr noget i artiklen - s uddyb venligst.
    • For at indstte f ord kode, brug <code>-taggen, for flere linjer - omslut dem i <pre>-tag, for mere end 10 linjer - brug en sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page