最根本的區別是陣列是乙個索引集合,這說明陣列中的資料值按索引排序。
const arr = [a, b, c, d];
console.log(arr.indexof(a)); // result: 0
console.log(arr.indexof(c)); // result: 2
相比之下,set
是乙個鍵的集合。set
不使用索引,而是使用鍵對資料排序。set
中的元素按插入順序是可迭代的,它不能包含任何重複的資料。換句話說,set
中的每一項都必須是惟一的。
set
相對於陣列有幾個優勢,特別是在執行時間方面:
陣列用來搜尋元素的方法時間複雜度為0(n)
。換句話說,執行時間的增長速度與資料大小的增長速度相同。
相比之下,set
用於搜尋、刪除和插入元素的方法的時間複雜度都只有o(1)
,這意味著資料的大小實際上與這些方法的執行時間無關。
雖然執行時間可能會有很大差異,具體取決於所使用的系統,所提供資料的大小以及其他變數,但我希望我的測試結果能夠讓你真實地了解set
的速度。我將分享三個簡單的測試和我得到的結果。
準備測試
在執行任何測試之前,建立乙個陣列和乙個 set,每個陣列和 set 都有100萬個元素。為了簡單起見,我從0
開始,一直數到999999
。
let arr = , set = new set(), n = 1000000;
for (let i = 0; i < n; i++)
測試1:查詢元素
我們搜尋數字123123
let result;
console.time('array');
result = arr.indexof(123123) !== -1;
console.timeend('array');
console.time('set');
result = set.has(123123);
console.timeend('set');
array: 0.173ms
set: 0.023ms
set
速度快了7.54
倍
測試2:新增元素
console.time('array');
arr.push(n);
console.timeend('array');
console.time('set');
set.add(n);
console.timeend('set');
array: 0.018ms
set: 0.003ms
set
速度快了6.73
倍
測試3:刪除元素
最後,刪除乙個元素,由於陣列沒有內建方法,首先先建立乙個輔助函式:
const deletefromarr = (arr, item) => ;
這是測試的**:
console.time('array');
deletefromarr(arr, n);
console.timeend('array');
console.time('set');
set.delete(n);
console.timeend('set');
array: 1.122ms
set: 0.015ms
set
速度快了74.13
倍
總的來說,我們可以看到,使用set
極大地改善執行時間。再來看看一些set
有用的實際例子。
案例1:從陣列中刪除重複的值
如果想快速地從陣列中刪除重複的值,可以將其轉換為乙個set
。這是迄今為止過濾惟一值最簡潔的方法:
const duplicatecollection = ['a', 'b', 'b', 'c', 'd', 'b', 'c'];
// 將陣列轉換為 set
let uniquecollection = new set(duplicatecollection);
console.log(uniquecollection) // result: set(4)
// 值儲存在陣列中
let uniquecollection = [...new set(duplicatecollection)];
console.log(uniquecollection) // result: ["a", "b", "c", "d"]
案例2:谷歌面試問題
問題:
給定乙個整數無序陣列和變數sum
,如果存在陣列中任意兩項和使等於sum
的值,則返回true
。否則,返回false
。例如,陣列[3,5,1,4]
和sum=9
,函式應該返回true
,因為4+5=9
。
解答
解決這個問題的乙個很好的方法是遍歷陣列,建立set
儲存相對差值。
當我們遇到3
時,我們可以把6
加到set
中, 因為我們知道我們需要找到9
的和。然後,每當我們接觸到陣列中的新值時,我們可以檢查它是否在set
中。當遇到5
時,在 set 加上4。最後,當我們最終遇到4
時,可以在set
中找到它,就返回true
。
const findsum = (arr, val) => else
};return false;
};
簡潔的版本:
const findsum = (arr, sum) =>
arr.some((set => n => set.has(n) || !set.add(sum - n))(new set));
因為set.prototype.has()
的時間複雜度僅為o(1)
,所以使用 set 來代替陣列,最終使整個解決方案的線性執行時為o(n)
。 處理Set集合
筆者不建議在 action 中使用set 集合屬性,因為 set集合裡元素處於無序狀態,所以 struts 2 不能準確地將請求引數轉換成 set元素。不僅如此,由於 set集合裡元素的無序性,所以 struts 2 也不能準確讀取 set集合裡的元素。除非set集合裡的元素有乙個標識屬性,這個標識...
處理Set集合
筆者不建議在 action 中使用set 集合屬性,因為 set集合裡元素處於無序狀態,所以 struts 2 不能準確地將請求引數轉換成 set元素。不僅如此,由於 set集合裡元素的無序性,所以 struts 2 也不能準確讀取 set集合裡的元素。除非set集合裡的元素有乙個標識屬性,這個標識...
處理集合 建立Set
使用內建建構函式建立set,如果不傳入任何引數,將建立乙個空set。可以傳入字串 new set kuma hattori yagyu hattori set成員的值都是唯一的,最重要的作用是避免儲存多個相同的物件。在本例子中,檢視新增兩次 hattori 但是只成功新增一次。set具有多個可訪問的...