J'ai créé une fonction pour vérifier s'il y a des numéros de téléphone portable répétés dans une liste. Le problème est que je l'ai fait en utilisant nested for. Comment pourrais-je optimiser ce code avec une programmation fonctionnelle?
checkDuplicate(): boolean {
for (let i = 0; i < this.phoneList.length; i++) {
for (let j = 0; j < this.phoneList.length; j++) {
if (i != j) {
if (this.phoneList[i].number === this.phoneList[j].number) {
this.toastrService.error('Phone already in List!');
return true;
}
}
}
}
return false;
}
6 Réponses :
encore mieux que le filtre (que j'ai suggéré dans un commentaire), utilisez Set - il y a plusieurs façons de le faire mais c'est assez propre. Cependant .filter () serait probablement considéré comme plus 'fonctionnel' car il s'agit d'un HOC
let a = [1,2,1,3,3,5] let x = [...new Set(a)] // => [1, 2, 3, 5]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
Propre en effet, mais il semble d'après le code de l'OP que chaque élément du tableau est un objet (d'où la référence à .number ), donc cela ne fonctionnera pas.
Vous pouvez faire quelque chose comme:
let dups = this.phoneList.filter(item =>
this.phoneList.filter(item2 => item.number == item2.number).length > 1
);
if (dups.length) {
this.toastrService.error('Phone already in List!');
return true;
}
... même si cela souffre un peu pour la lisibilité.
" bien qu'il en souffre un peu pour la lisibilité. " et les performances, car c'est O (n ^ 2) identique à la solution d'OP.
Ce n'est pas une fonctionnalité mais c'est la plus rapide à ce jour.
const checkDuplicate = (phones)=> {
let counts = {};
for(let phone of phones) {
if(counts[phone.number]) return true;
counts[phone.number] = 1;
}
return false;
}
if(checkDuplicate(this.phoneList)) {
this.toastrService.error('Phone already in List!');
}
Veuillez expliquer comment votre réponse compare this.phoneList.number pour les doublons
Cela échoue toujours, changez en let count = {}; pour utiliser correctement la propriété d'objet de cette façon
Vous pouvez utiliser Array.some pour vérifier si un numéro de téléphone est un doublon, comme indiqué ci-dessous. Dans la boucle de rappel, le numéro de téléphone est la clé d'une valeur booléenne ajoutée à l'objet exist . La boucle s'arrête dès que la fonction de rappel renvoie true , ce qui se produit lorsqu'une clé / valeur correspondant à l'élément de la boucle est trouvée dans existe .
checkDuplicate(): boolean {
let exists: { [key: number]: boolean } = {};
return this.phoneList.some(phoneListItem => {
if (exists[phoneListItem.number]) {
return true;
} else {
exists[phoneListItem.number] = true;
return false;
}
});
}
Vous pouvez créer un ensemble contenant uniquement les nombres uniques et comparer la longueur de l'ensemble à la longueur du tableau d'origine
hasDuplicates(): boolean {
return new Set(this.phoneList.map(p => p.number)).size < this.phoneList.length
}
Ce n'est pas vraiment une question angulaire mais juste du JavaScript. Vous pouvez simplement faire un cycle court la boucle sur la liste comme plus rapide.
Chaque boucle interne est n-i plus rapide (moins à faire / vérifier) puisque nous avons déjà vérifié ces
var xObj = {
phoneList: [{
name: "freddy",
number: 55512121234
}, {
name: "Jimmy",
number: 55512121234
}, {
name: "Mommy",
number: 55512121233
},
{
name: "Tommy",
number: 55512121244
},
{
name: "Luka",
number: 55512121222
},
{
name: "Penny",
number: 55512121255
},
{
name: "Sammy",
number: 55512121266
},
{
name: "Bill",
number: 55512121244
}
],
phoneList2: [{
name: "freddy",
number: 55512121234
}, {
name: "Jimmy",
number: 55512121235
}, {
name: "Mommy",
number: 55512121233
},
{
name: "Tommy",
number: 55512121244
},
{
name: "Luka",
number: 55512121222
},
{
name: "Penny",
number: 55512121259
},
{
name: "Sammy",
number: 55512121266
},
{
name: "Bill",
number: 55512121247
}
],
toastrService: {
error: function(message) {
console.log(message);
}
},
checkDuplicate: function() {
let hasDupe = false
for (let i = 0; i < this.phoneList.length; i++) {
for (let j = i + 1; j < this.phoneList.length; j++) {
if (this.phoneList[i].number === this.phoneList[j].number) {
hasDupe = true;
break;
}
}
if (hasDupe) break;
}
if (hasDupe) this.toastrService.error('Phone already in List!');
return hasDupe;
},
checkDuplicate2: function() {
let hasDupe = false
for (let i = 0; i < this.phoneList2.length; i++) {
for (let j = i + 1; j < this.phoneList2.length; j++) {
if (this.phoneList2[i].number === this.phoneList2[j].number) {
hasDupe = true;
break;
}
}
if (hasDupe) break;
}
if (hasDupe) this.toastrService.error('Phone already in List!');
return hasDupe;
}
};
let cdup = xObj.checkDuplicate();
let cdup2 = xObj.checkDuplicate2();
console.log("dup:", cdup, cdup2);
C'est encore O (n ^ 2) . Oui, c'est plus rapide que de parcourir tout le tableau, mais cela ne change pas la complexité temporelle.
Cela dépend également du tableau puisque si le premier et le deuxième correspondent ou si le deuxième et le troisième correspondent, cela se fait à ce point avec true. Cela fonctionne également sur les anciens navigateurs.
Les navigateurs plus anciens n'ont pas Set, mais vous pouvez toujours utiliser un objet simple et vous pouvez en utiliser un pour parcourir le tableau et suivre les valeurs. Vous obtenez toujours une récupération en temps constant et toute la complexité de l'algorithme est O (n) . En fait, avec un objet, vous aurez l'avantage d'avoir la même complexité du meilleur cas et une bien meilleure complexité moyenne et pire des cas.
checkout
Array.filter ()L'optimal dépendra également des données et du navigateur réels, car sur des navigateurs très anciens, un
tandis que (this.phoneList.length--)sera plus rapideEst-ce que cela répond à votre question? Supprimer les doublons d'un tableau d'objets dans JavaScript