2017-10-10 7 views
0

J'ai créé un prototype personnalisé avec lequel nettoyer un tableau afin de supprimer les doublons et sorte il. Il a travaillé et ressemblait à ceci:Modifier un tableau en place avec le prototype

// given an example array such as this. 
var names = [ 'Lara', 'Lucy', 'Alexa', 'Vanessa', 'Lucy', 'Brianna', 'Sandra' ]; 

Array.prototype.clean_up = function(){ 
    var 
     set = [] 
    ; 
    this.forEach(function(item){ 
     if (set.indexOf(item) === -1) { 
      set.push(item); 
     } 
    }); 

    set.sort(); 

    return set; 
}; 

Mon seul reproche est que je dois l'appeler comme ceci:

names = names.clean_up(); 

Je préférerais que si je pouvais l'appeler comme suit, comme Array.sort() (I croire que cela s'appelle une mise en œuvre sur place). Comment pouvez vous faire ça?

names.clean_up(); 

EDIT: (Apparemment, cela appartient ici et non réponses)

Ma solution actuelle se présente comme suit, mais il se sent un peu inefficace. Je me demande si cela pourrait être mieux fait.

Array.prototype.clean_up = function(){ 
    var 
     set = [], 
     self = this 
    ; 
    this.forEach(function(item){ 
     if (set.indexOf(item) === -1) { 
      set.push(item); 
     } 
    }); 

    set.sort(); 

    // reset and re-fill. 
    while (this.length > 0) { 
     this.pop(); 
    } 

    set.forEach(function(item){ 
     self.push(item); 
    }); 
}; 

Inefficace pour l'un, et pour l'autre: il a été mentioned à plusieurs reprises que vous ne devriez pas modifier les tableaux originaux. Pourquoi donc?

Je veux dire, s'il y a une fonction comme Array.sort() il montre que la langue est capable de le faire, et que quelques implémentations semblent être « d'accord »? Pourquoi est sort() ok mais une fonction personnalisée non?

Répondre

0

Si vous voulez affecter la matrice en place, recherchez les doublons et splice à partir de la matrice. Array.prototype.indexOf peut être utilisé avec un deuxième argument pour rechercher à partir de l'élément en cours et supprimer les dupes, par ex.

Array.prototype.clean = function(){ 
 
    // Iterate backwards over array 
 
    this.reduceRight(function(acc, value, index, arr) { 
 
    // If first index of value isn't current index, remove this element 
 
    if (arr.indexOf(value) != index) arr.splice(index, 1); 
 
    }, null); 
 
    // Now sort 
 
    this.sort(); 
 
    // Return for chaining 
 
    return this; 
 
} 
 

 
var arr = 'aztatffgff'.split(''); 
 
console.log(arr.join()); 
 
console.log(arr.clean().join());

avant itérez un tableau ne fonctionne pas parce que lorsque les éléments sont épissés, les éléments sont brassés vers le bas de sorte que le prochain est sautée. Vous ne pouvez pas simplement créer un tableau en utilisant, disons, le filtre parce que vous ne pouvez pas affecter ce nouveau tableau à ce.

reduceRight peut être remplacé par un pour boucle.

+0

Il est un peu difficile d'envelopper votre tête, et imo non intuitive avec le 'reduceRight', mais il fait parfaitement ce que je veux. Je vous remercie. Fondamentalement, l'utilisation de 'splice' est la clé (par rapport à mon code). – WoodrowShigeru

+0

@ WoodrowShigeru - s'il y avait un * forEachRight *, je l'utiliserais. ;-) – RobG