Avatar billede molte Nybegynder
08. februar 2009 - 19:51 Der er 10 kommentarer og
1 løsning

Slette fælles værdier i to arrays

Jeg har to arrays og vil gerne sammenligne dem og slette de værdier, de har til fælles.
De kunne fx se således ud (de vil nok være lidt længere rigtigt):
navne1 = ["Ursula", "Benny", "Svend"];
navne2 = ["Benny, "Tove"];
Da skulle de gerne komme til at se sådan ud:
navne1 = ["Ursula", "Svend"];
navne2 = ["Tove"];

Hvad skal jeg gøre for at opnå dette?
Avatar billede olebole Juniormester
08. februar 2009 - 20:34 #1
<ole>

Måske noget à la:

function arrRemoveDuplicates(aA, aB) {
    for (var i=aA.length-1; i>=0; i--) {
        for (var j=aB.length-1; j>=0; j--) {
            if (aA[i]==aB[j]) {
                aA.splice(i, 1);
                aB.splice(j, 1);
            }
        }
    }
    return [aA, aB];
}

var navne1 = ["Ursula", "Benny", "Svend"];
var navne2 = ["Benny", "Tove"];

var a = arrRemoveDuplicates(navne1, navne2);

alert(a[0].join(" :: "));
alert(a[1].join(" :: "));

/mvh
</bole>
Avatar billede molte Nybegynder
08. februar 2009 - 20:42 #2
Tak for svaret.
Er der slet ingen måde at gøre det på uden alle de løkker?

Off topic: Jeg har lige læst dine artikler om XHTML fra 2004 - hvornår kommer fortsættelsen?
Avatar billede molte Nybegynder
08. februar 2009 - 20:56 #3
Er der for resten nogen grund til, du lader løkkerne tælle ned ad i stedet for op?
Avatar billede olebole Juniormester
08. februar 2009 - 20:58 #4
Nej, der findes ikke metoder til den slags i JavaScript, så du kommer deværre ikke udenom løkkerne - og nestede løkker er jo aldrig lykken  :o|
Ellers skal du måske overveje en anden struktur(?)

Jeg opgav i sin tid skriveriet i artikel interface'et i det gamle Eksperten design - det var mildt sagt elendigt at arbejde i. Derfor påbegyndte jeg www.dengodekode.dk - men arbejde har bremset projektet. Jeg har dog en (re)lacering i kalenderen i løbet af foråret  =)
Avatar billede molte Nybegynder
08. februar 2009 - 21:04 #5
Meget vel, så læg du bare et svar...
Avatar billede olebole Juniormester
08. februar 2009 - 21:22 #6
Nu er der jo ganske vist en indexOf metode på Array objektet fra JS 1.6, men den version er kun understøttet fra Firefox 3.0.

I stedet har jeg skrevet en lille extension af Array objektets prototype, som bliver kørt i browsere, der ikke understøtter JS 1.6. Faktisk virker dette ovenikøbet også lidt hurtigere i disse browsere, end det jeg viste før  =)

/*
    From JavaScript 1.6 (Firefox 3.0) the prototype of
    the Array object supports the method 'indexOf'.
    If not supported: Extend the Array prototype.
*/
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(o,nI) {
        if (nI==null) nI = 0;
        else if (nI<0) nI = Math.max(0, this.length+nI);
        for (var i=nI,j=this.length; i<j; i++) if (this[i]===o) return i;
        return -1;
    };
}

function arrRemoveDuplicates(aA, aB) {
    for (var i=aA.length-1; i>=0; i--) {
        nInx = aB.indexOf(aA[i]);
        if (nInx>-1) {
            aA.splice(i, 1);
            aB.splice(nInx, 1);
        }
    }
    return [aA, aB];
}

var navne1 = ["Ursula", "Benny", "Svend"];
var navne2 = ["Benny", "Tove"];

var a = arrRemoveDuplicates(navne1, navne2);
Avatar billede olebole Juniormester
08. februar 2009 - 23:50 #7
Tak for points  =)

Hvis du yderligere extend'er Array med forEach (også fra JS 1.6), kan du skrive:

if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(f /*, o*/) {
        if (typeof f!="function") throw new Error("Array.forEach :: Argument is of wrong type.");
        for (var i=0,j=this.length; i<j; i++) {
            if (i in this) f.call(arguments[1], this[i], i, this);
        }
    };
}

var navne1 = ["Ursula", "Benny", "Svend"];
var navne2 = ["Benny", "Tove"];

function foo(sVal, nInx, aArr) {
    var nFound = this.indexOf(sVal);
    if (nFound>-1) {
        aArr.splice(nInx, 1);
        this.splice(nFound, 1);
    }
}

navne2.forEach(foo, navne1);

alert(navne1.join(" - "))
alert(navne2.join(" - "))

- men i browsere, som endnu ikke naturligt understøtter de to Array-metoder, undgår du stadig ikke loops  =)
Avatar billede olebole Juniormester
09. februar 2009 - 00:00 #8
forEach tager to argumenter:
1) En funktion, som køres for hvert element i array'et.
    Til denne funktion medsendes tre argumenter: Array-elementet, index og array'et selv.

2) Et objekt, funktionen skal scopes til. Dvs, at 'this' inde i funktionen vil pege på dette objekt - og ikke som forventet på window objektet.
Avatar billede molte Nybegynder
09. februar 2009 - 00:02 #9
Tak.
Jeg kan faktisk godt bruge både forEach og indexOf da det skal foregå server-side, og den server jeg bruger (Jaxer) bruger Mozilla Firefox 3's js engine.
Avatar billede olebole Juniormester
09. februar 2009 - 00:09 #10
Så er det bare på med luffen!  ;o)

PS: Det andet argument i forEach er valgfrit. Udelades det, vil 'this' i funktionen som ventet pege på window.

I dit tilfælde er det dog oplagt at scope funktionen til det andet array.
Avatar billede olebole Juniormester
09. februar 2009 - 00:12 #11
Jaxer udfører faktisk de samme handlinger, men da det foregår et niveau dybere, går det væsentligt hurtigere  ;o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester