Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[JS] In array duplicaten voorkomen bij push of na afloop?

Pagina: 1
Acties:

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Momenteel maak ik gebruik van .push om een javascript array op te bouwen met waarden die ik aangeleverd krijg vanuit XML, echter is het zo dat de bron dubbele waarden verstuurd en deze zou ik willen opschonen.

Nu is mijn vraag hoe ik dit het beste kan doen. Is het verstandig om aan de array middels prototype een functie toe te voegen die de push anders afhandelt door meteen te controleren of de waarde al bestaat, of kan ik dat beter na afloop doen middels code die op onderstaand voorbeeld lijkt:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
Object.extend(Array.prototype, {
reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  }
}
bron: Prototype Javascript framework: Array
Welke oplossing is beter voor wat betreft de performance?

Verwijderd

Gebruik je value als key?

Zo ben je zeker dat iedere bron maar 1 keer voorkomt.

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Nee, ik doe het op de volgende manier:

JavaScript:
1
2
var DeArray=[];
DeArray.push(ResponsXML.firstChild.nodeValue);

Verwijderd

ik weet da je .push() gebruikt, maar als je nu ipv je data als value in je array te stoppen, die data als key in je array stopt ben je toch zeker dat die data maar 1 keer voorkomt in je array? Keys zijn afaik uniek.

Verwijderd

Is de volgorde van de elementen in de array van belang? Zo niet dan zou ik zeker de array achteraf opschonen. Het is het verschil tussen voor elk nieuw element de complete array doorlopen voor een dupe en de array maar een keer doorlopen.

Wat Array prototypen betreft...als je deze actie niet regelmatig in je code terugkomt zou ik dat zeker niet doen. Dan is een simpele losse functie meer dan voldoende:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function UniqueArray( myArray ) {
    myArray = myArray.sort();
    var aUnique = new Array();
    var iValue = null;
    for(var i=0; i<myArray.length; i++) {
        if(myArray[i] != iValue) {
            aUnique[aUnique.length] = myArray[i];
        }
        iValue = myArray[i];
    }
    return aUnique;
}

var a = [1,2,54,12,2,1,3,4,5];
var b = UniqueArray( a );

(uit [Actionscript 2.0] Uniek Array)

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Verwijderd schreef op vrijdag 31 augustus 2007 @ 11:42:
Is de volgorde van de elementen in de array van belang? Zo niet dan zou ik zeker de array achteraf opschonen. Het is het verschil tussen voor elk nieuw element de complete array doorlopen voor een dupe en de array maar een keer doorlopen.
Volgorde is wel van belang, maar dat kan ik toch beter achteraf doen met .sort() en zo had ik er nog niet naar gekeken, achteraf is sneller, anders blijf je de array doorlopen en nu heb ik soms al > 200 waarden.
Wat Array prototypen betreft...als je deze actie niet regelmatig in je code terugkomt zou ik dat zeker niet doen. Dan is een simpele losse functie meer dan voldoende:
JavaScript:
1
mooi voorbeeld
(uit [Actionscript 2.0] Uniek Array)
Bedankt voor deze tip. De functie wordt maar eenmalig gebruikt, dus prototypen zal ik dan wel achterwege laten. Dit topic had ik nog niet gevonden, had andere woorden (zoals, dubbel, duplicaten, double, ipv uniek) gebruikt bij het zoeken.

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Een array_unique achteraf makes sense aangezien je daarmee je primaire functies vrij houd van complexiteit en daarmee duidelijk houdt. Zoals je ziet is het behoorlijk triviaal een dergelijke functie te maken, een alternatief zou zijn om door de array heen te lopen en ondertussen een hashmap bij te houden, op die manier kan je de volgorde gelijk houden (hoef je zelfs geen kopie te maken van je array maar kan je 'm direct bewerken). Je zou het rond een Array.filter kunnen schrijven (native in Firefox 3.0) - Firefox heeft sowieso een aantal handige native Array methods (zie mijn blog voor crossbrowser voorbeelden).

Intentionally left blank


  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Na het artikel gelezen te hebben op crisp zijn blog moet ik zeggen dat het gebruik maken van .filter() het mooiste is omdat je dan gebruik maakt van (toekomstige) native array methods, zie de generic.js en deze documentatie bij Mozilla.

Enige nadeel (naar mijn idee) is dat deze methods geen bewerking uitvoeren op de bestaande array en dat je deze dan als volgt zou moeten toepassen:
JavaScript:
1
2
var ar = [a, b, c, d, b, a, e];
ar = ar.filter(uniqueEl);


Wat mij in deze situatie alleen nog niet duidelijk is, is hoe ik zelf aan de hand van dit voorbeeld de functie uniqueEl() zou moeten schrijven, iets als pseudocode:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
function uniqueEl(element, index, array) {

  for (var el in array)
  {
    if (array[el] == element)
    {
      return el;
      break;
    }
  }
}


Weet overigens niet of dit werkt, want heb de pseudocode hier vandaan. Overigens lijkt dit er dan weer op dat ik de array meerdere malen (onnodig?) aan het doorlopen ben, wat wellicht weer ten koste gaat van de performance.

[ Voor 16% gewijzigd door Woudloper op 31-08-2007 16:17 ]


  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
omdat ik enige tijd op vakantie geweest ben en ik na mijn vakantie er nog niet uit ben doe ik het op deze manier,
schop >:)

Iemand nog een idee hoe ik de function moet maken die wordt gebruikt binnen de (native) .filter methode? Het voorbeeld is bovenstaande reactie is nu aangepast (dus geen psuedo meer), maar om de één of andere reden werkt het niet.

Iemand een idee wat ik fout doe bij deze functie en waarom deze niet werkt binnen de .filter() methode?

Verwijderd

Woudloper schreef op maandag 17 september 2007 @ 15:13:
Iemand nog een idee hoe ik de function moet maken die wordt gebruikt binnen de (native) .filter methode? Het voorbeeld is bovenstaande reactie is nu aangepast (dus geen psuedo meer), maar om de één of andere reden werkt het niet.
Dit is een dirty quicky:
JavaScript:
1
2
3
4
5
6
7
8
9
10
function uniqueEl(el, index, array) {
    var found = false;
    for(var i = 0; i < index; i++) {
        if(array[i] == el) {
             found = true;
             break;
        }
    }
    return !found
}

Ff heel rechtoe-rechtaan: de filter methode itereert van voor naar achter door het array en geeft een-voor-een elk element door aan de uniqueEl functie. Daar hoeven we voor elk element dus alleen even te checken of 'ie al eerder is voorgekomen: in uniqueEl itereren we dus van 0 tot index en we houden bij of we de huidige waarde tegenkomen. Zo ja, dan returnen we false. Waarom? Omdat de huidige waarde er niet in hoeft te blijven. :)

Dit kan vast wel mooier maar het werkt ;)
Pagina: 1