目錄
寫在最後
#(相關免費學習推薦:javascript影片教學)
一、雙層循環
const unique = (arr)=>{ for(let i = 0; i { var arr = [1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1]; var newArr = []; for(let i = 0; i <p><strong>核心點:</strong></p>
O(n^2)
二、indexOf和includes
核心點:
indexOf
方法找到重複項時(不等於它首次出現的位置)時利用splice
移除indexOf
:傳回在陣列中可以找到一個給定元素的第一個索引
,如果不存在,則返回-1。 indexOf(ele, fromIndex)
程式碼:
const unique = (arr) => { var res = []; for (let i = 0; i <h5>2.2 includes簡化一層循環判斷</h5><p> <strong>#核心點:</strong></p>
includes
:用來判斷陣列是否包含指定的值,根據情況,如果包含則傳回true
,否則傳回false
includes(ele, fromIndex)
fromIndex
的絕對值個索引。 。 ##
const unique = (arr) => { var res = []; for (let i = 0; i 2.3 indexOf和includes對於目前場景的選擇<h5></h5>在這裡我們推薦使用includes來尋找元素:<p></p><p>傳回值可以直接作為if的條件語句,簡潔<strong></strong></p><pre class="brush:php;toolbar:false">if(res.indexOf(arr[i]) !== -1 ){ todo }// orif(res.includes(arr[i])){ todo }##識別
NaN如果數組中有
,你又剛好需要判斷數組是否有存在NaN
,這時你用indexOf
是無法判斷的,你必須使用includes
這個方法。 <pre class="brush:php;toolbar:false">var arr = [NaN, NaN];arr.indexOf(NaN); // -1arr.includes(NaN); // true</pre>
undefined#如果陣列中有
值,includes
#會認為空的值是undefined
,而indexOf則不會。 <pre class="brush:php;toolbar:false">var arr = new Array(3);console.log(arr.indexOf(undefined)); //-1console.log(arr.includes(undefined)) //true</pre>
核心點:
陣列排序後,相同的元素會相鄰,所以如果當前元素與它的相鄰元素不同,就存入到新數組中;
var arr = [1, 1, '1'];function unique(arr) { var res = []; var sortedArr = arr.concat().sort(); var last; for (var i = 0; i <strong></strong>四、filter<p><strong># #核心點:</strong></p><p><strong>filter:方法建立一個新陣列, 其包含透過所提供</strong>函數實現的測試</p>的所有元素(傳回測試函數成立的元素)
filter(callback, thisArg)
:
thisArg:執行callback 時,用於this 的值。 var arr = [1, 2, 1, 1, '1'];const unique = function (arr) { var res = arr.filter(function(item, index, arr){ return arr.indexOf(item) === index; }) return res;}console.log(unique(arr)); // [ 1, 2, '1' ]
結合排序的思路:var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
return arr.concat().sort().filter(function(item, index, arr){
return !index || item !== arr[index - 1]
})}console.log(unique(arr));
#前面提到的幾種方式總結下來大致分為
非排序數組,兩次遍歷判斷(遍歷、查詢)排序數組,相鄰元素比較舉例:
obj
的key
而不管他们的value
var arr = [1, 2, 1, 1, '1', 3, 3];const unique = function(arr) { var obj = {}; var res = []; arr.forEach(item => { if (!obj[item]) { obj[item] = true; res.push(item); } }); return res;}console.log(unique(arr)); // [1, 2, 3]
var arr = [1, 2, 1, 1, '1'];const unique = function(arr) { var obj = {}; return arr.filter(function(item, index, arr){ return obj.hasOwnProperty(item) ? false : (obj[item] = true) })}console.log(unique(arr)); // [1, 2]
对象的属性是字符串类型的,即本身数字1
和字符串‘1’
是不同的,但保存到对象中时会发生隐式类型转换,导致去重存在一定的隐患。
考虑到string和number的区别(typeof 1 === ‘number’, typeof ‘1’ === ‘string’),
所以我们可以使用 typeof item + item
拼成字符串作为 key 值来避免这个问题:
var arr = [1, 2, 1, 1, '1', 3, 3, '2'];const unique = function(arr) { var obj = {}; var res = []; arr.forEach(item => { if (!obj[typeof item + item]) { obj[typeof item + item] = true; res.push(item); } }); return res;}console.log(unique(arr)); // [ 1, 2, '1', 3, '2' ]
六、ES6
随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构。
Set:它允许你存储任何类型的唯一值,无论是原始值或者是对象引用
代码:
var arr = [1, 2, 1, '1', '2'];const unique = function(arr) { return Array.from(new Set(arr));}console.log(unique(arr)); // [ 1, 2, '1', '2' ]
简化1:
function unique(array) { return [...new Set(array)];}
简化2:
var unique = (a) => [...new Set(a)]
Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。
function unique (arr) { const newMap = new Map() return arr.filter((a) => !newMap.has(a) && newMap.set(a, 1));}
写到这里比较常规的数组去重方法就总结的差不多了,如果需要更强大的去重方法,我们需要对他们进行组合,而且因为场景的不同,我们所实现的方法并不一定能涵盖到
相关免费学习推荐:javascript(视频)
以上是JavaScript專題之二:陣列去重的詳細內容。更多資訊請關注PHP中文網其他相關文章!