Maison >interface Web >js tutoriel >Méthode de déduplication de tableau JavaScript
Nous savons tous que différents langages de programmation ont une déduplication de tableau. Dans cet article, nous parlerons de la déduplication de tableau JavaScript, dans l'espoir d'aider tout le monde.
Boucle double couche
La première chose à laquelle nous pensons est peut-être d'utiliser indexOf pour parcourir le jugement, mais avant cette méthode, jetons un coup d'œil à la méthode la plus originale :
var array = [1, 1, '1', '1'];function unique(array) { // res用来存储结果 var res = []; for (var i = 0, arrayLen = array.length; i < arrayLen; i++) { for (var j = 0, resLen = res.length; j < resLen; j++ ) { if (array[i] === res[j]) { break; } } // 如果array[i]是唯一的,那么执行完循环,j等于resLen if (j === resLen) { res.push(array[i]) } } return res; }console.log(unique(array)); // [1, "1"]
Dans cette méthode, nous utilisons l'imbrication de boucles, le tableau de boucles le plus externe et la boucle interne res Si la valeur de array[i] est égale à la valeur de res[j], sortez de. la boucle. S'ils ne sont pas égaux, expliquez que l'élément est unique. À ce moment, la valeur de j sera égale à la longueur de res. Jugez en fonction de cette caractéristique et ajoutez la valeur à res.
Cela semble très simple. La raison pour laquelle je veux parler de cette méthode est parce que————elle a une bonne compatibilité !
indexOf
Nous pouvons utiliser indexOf pour simplifier la boucle interne :
var array = [1, 1, '1'];function unique(array) { var res = []; for (var i = 0, len = array.length; i < len; i++) { var current = array[i]; if (res.indexOf(current) === -1) { res.push(current) } } return res; }console.log(unique(array));
Déduplication après le tri
Imaginez que nous allons d'abord dédupliquer le tableau après En triant à l'aide de la méthode de tri, les mêmes valeurs seront triées ensemble. Ensuite, nous ne pouvons que juger si l'élément actuel est le même que l'élément précédent. S'ils sont identiques, cela signifie une duplication. ajoutons-les à res. Écrivons une démo :
var array = [1, 1, '1'];function unique(array) { var res = []; var sortedArray = array.concat().sort(); var seen; for (var i = 0, len = sortedArray.length; i < len; i++) { // 如果是第一个元素或者相邻的元素不相同 if (!i || seen !== sortedArray[i]) { res.push(sortedArray[i]) } seen = sortedArray[i]; } return res; }console.log(unique(array));
Si nous dédupliquons un tableau trié, cette méthode est nettement plus efficace que l'utilisation de indexOf.
API unique
Après avoir connu ces deux méthodes, nous pouvons essayer d'écrire une fonction outil appelée unique. Nous déterminons si le tableau entrant est dupliqué en fonction d'un paramètre isSorted. nous jugerons si les éléments adjacents sont les mêmes. Si c'est faux, nous utiliserons indexOf pour juger de l'
var array1 = [1, 2, '1', 2, 1];var array2 = [1, 1, '1', 2, 2];// 第一版function unique(array, isSorted) { var res = []; var seen = []; for (var i = 0, len = array.length; i < len; i++) { var value = array[i]; if (isSorted) { if (!i || seen !== value) { res.push(value) } seen = value; } else if (res.indexOf(value) === -1) { res.push(value); } } return res; }console.log(unique(array1)); // [1, 2, "1"]console.log(unique(array2, true)); // [1, "1", 2]
Optimisation
Bien qu'unqique puisse déjà essayer la fonction de déduplication, afin de Pour rendre cette API plus puissante, considérons une exigence :
Nouvelle exigence : Les majuscules et les minuscules des lettres sont considérées comme cohérentes, comme 'a' et 'A', gardez-en simplement une !
Bien que nous puissions d'abord traiter toutes les données du tableau, par exemple en convertissant toutes les lettres en minuscules, puis les transmettre à la fonction unique, existe-t-il un moyen de sauvegarder cette boucle de traitement du tableau et simplement le faire directement ? Et si vous le faisiez dans un cycle de déduplication ? Remplissons cette exigence :
var array3 = [1, 1, 'a', 'A', 2, 2];// 第二版// iteratee 英文释义:迭代 重复function unique(array, isSorted, iteratee) { var res = []; var seen = []; for (var i = 0, len = array.length; i < len; i++) { var value = array[i]; var computed = iteratee ? iteratee(value, i, array) : value; if (isSorted) { if (!i || seen !== value) { res.push(value) } seen = value; } else if (iteratee) { if (seen.indexOf(computed) === -1) { seen.push(computed); res.push(value); } } else if (res.indexOf(value) === -1) { res.push(value); } } return res; }console.log(unique(array3, false, function(item){ return typeof item == 'string' ? item.toLowerCase() : item })); // [1, "a", 2]
Dans cette version et la dernière de l'implémentation, la fonction passe trois paramètres :
array : représente le tableau à supprimer les doublons, qui doit être Fill in
isSorted : indique si le tableau transmis par la fonction a été trié. Si c'est vrai, une méthode plus rapide sera utilisée pour supprimer les doublons
iteratee : transmet une fonction qui. peut trier le tableau. Chaque élément est recalculé, puis dédupliqué en fonction des résultats du traitement
À ce stade, nous avons écrit une fonction unique suivant l'idée du soulignement. Vous pouvez consulter Github pour plus de détails.
filter
ES5 fournit la méthode filter, que nous pouvons utiliser pour simplifier la boucle externe :
Par exemple, utilisez la méthode indexOf :
var array = [1, 2, 1, 1, '1'];function unique(array) { var res = array.filter(function(item, index, array){ return array.indexOf(item) === index; }) return res; }console.log(unique(array));
Méthodes de tri pour supprimer les doublons :
var array = [1, 2, 1, 1, '1'];function unique(array) { return array.concat().sort().filter(function(item, index, array){ return !index || item !== array[index - 1] }) }console.log(unique(array));
Paire clé-valeur d'objet
Il existe de nombreuses méthodes pour supprimer les doublons Bien que nous ayons déjà écrit une API unique suivant le trait de soulignement, regardons. dans d'autres extensions de méthodes Vue inférieure :
Cette méthode utilise un objet Object vide. Nous stockons la valeur du tableau comme valeur clé de l'objet, par exemple Object[value1] = true. if Object Si [value2] existe, cela signifie que la valeur est répétée. L'exemple de code est le suivant :
var array = [1, 2, 1, 1, '1'];function unique(array) { var obj = {}; return array.filter(function(item, index, array){ return obj.hasOwnProperty(item) ? false : (obj[item] = true) }) }console.log(unique(array)); // [1, 2]
Nous pouvons constater qu'il y a un problème car 1 et '1' sont différents, mais cette méthode jugera qu'il s'agit de la même valeur en raison de la valeur clé de l'objet Il ne peut s'agir que d'une chaîne, nous pouvons donc utiliser typeof item + item pour former une chaîne comme valeur clé pour éviter ce problème :
var array = [1, 2, 1, 1, '1'];function unique(array) { var obj = {}; return array.filter(function(item, index, array) { return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true) }) }console.log(unique(array)); // [1, 2, "1"]
ES6
Avec l'arrivée de ES6, déduplication Il y a eu des progrès dans la méthode. Par exemple, nous pouvons utiliser les structures de données Set et Map. En prenant Set comme exemple, ES6 fournit une nouvelle structure de données Set. C'est similaire à un tableau, mais les valeurs des membres sont uniques et il n'y a pas de valeurs en double.
Avez-vous l’impression que vous vous préparez à perdre du poids ? Écrivons une version :
var array = [1, 2, 1, 1, '1'];function unique(array) { return Array.from(new Set(array)); }console.log(unique(array)); // [1, 2, "1"]
Elle peut même être simplifiée davantage :
function unique(array) { return [...new Set(array)]; }
Elle peut également être simplifiée davantage :
var unique = (a) => [...new Set(a)]
De plus, si vous utilisez les mots de Map :
function unique (arr) { const seen = new Map() return arr.filter((a) => !seen.has(a) && seen.set(a, 1)) }
L'évolution de JavaScript
On voit que la méthode de déduplication est passée des 14 lignes de code d'origine à 1 ligne de code d'ES6, ce qui illustre en fait le langage JavaScript Avec des progrès continus, je pense que les développements futurs deviendront de plus en plus efficaces.
Comparaison de types spéciaux
Cela met fin à la méthode de déduplication. Cependant, les types d'éléments à dédupliquer peuvent être divers, à l'exception du simple 1 et '1' dans l'exemple, en fait. il y a aussi des objets nuls, non définis, NaN, etc. Alors pour ces éléments, quel est le résultat de la déduplication des méthodes précédentes ?
Avant cela, regardons quelques exemples :
var str1 = '1';var str2 = new String('1');console.log(str1 == str2); // trueconsole.log(str1 === str2); // falseconsole.log(null == null); // trueconsole.log(null === null); // trueconsole.log(undefined == undefined); // trueconsole.log(undefined === undefined); // trueconsole.log(NaN == NaN); // falseconsole.log(NaN === NaN); // falseconsole.log(/a/ == /a/); // falseconsole.log(/a/ === /a/); // falseconsole.log({} == {}); // falseconsole.log({} === {}); // false
Donc, pour un tel tableau
var array = [1, 1, '1', '1', null, null, undefined, undefined, new String('1'), new String('1'), /a/, /a/, NaN, NaN];
les méthodes ci-dessus peuvent être utilisées pour supprimer les doublons Quel est le résultat ?
J'ai spécialement compilé une liste, nous nous concentrons sur la déduplication des objets et NaN :
Description du résultat de la méthode
for boucle [1, "1", null, undefined, String, String, /a/, /a/, NaN, NaN] Les objets et NaN ne sont pas dupliqués
indexOf [1, "1", null, undefined, String, String, /a/, /a/, NaN, NaN] 对象和 NaN 不去重
sort [/a/, /a/, "1", 1, String, 1, String, NaN, NaN, null, undefined] 对象和 NaN 不去重 数字 1 也不去重
filter + indexOf [1, "1", null, undefined, String, String, /a/, /a/] 对象不去重 NaN 会被忽略掉
filter + sort [/a/, /a/, "1", 1, String, 1, String, NaN, NaN, null, undefined] 对象和 NaN 不去重 数字 1 不去重
优化后的键值对方法 [1, "1", null, undefined, String, /a/, NaN] 全部去重
Set [1, "1", null, undefined, String, String, /a/, /a/, NaN] 对象不去重 NaN 去重
想了解为什么会出现以上的结果,看两个 demo 便能明白:
// demo1var arr = [1, 2, NaN];
arr.indexOf(NaN); // -1
indexOf 底层还是使用 === 进行判断,因为 NaN ==== NaN的结果为 false,所以使用 indexOf 查找不到 NaN 元素
// demo2function unique(array) { return Array.from(new Set(array)); }console.log(unique([NaN, NaN])) // [NaN]
Set 认为尽管 NaN === NaN 为 false,但是这两个元素是重复的。
写在最后
虽然去重的结果有所不同,但更重要的是让我们知道在合适的场景要选择合适的方法。
以上内容就是各种不同的JavaScript数组去重方法,如果大家觉得有用的话赶紧收藏起来吧。
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!