前端面試手寫練習 - isEqual
- 文章發表於
問題
當我們想要按值而不是按引用比較複雜的數據類型時,isEqual
非常有用。這篇文章將討論如何實作一個 isEqual
函式,我們需要能夠支援以下數據類型:
- 原始類型 (primitives)
- 物件 (plain objects, object literals)
- 陣列 (arrays)
function isEqual(a: any, b: any): boolean
範例
isEqual
非常直觀,它將兩個值進行比較,如果它們是相等的,則返回 true
,否則返回 false
。
const obj1 = { a: 1, b: 2 }const obj2 = { a: 1, b: 2 }console.log(isEqual(obj1, obj2)) // trueconst arr1 = [1, obj1, 3]const arr2 = [1, obj2, 3]console.log(isEqual(arr1, arr2)) // true
練習區
在了解問題後,可以嘗試先寫下您的思路,再到下方的練習區域實際寫出程式碼。
追問
- 如何處理陣列或是物件中的循環引用 (circular references)? (Hint: 使用 WeakMap)
筆者思路
定義 base case
- 如果
a === b
直接回傳true
- 如果
如果 a 與 b 都是陣列
- 如果 b 長度與 a 不同,直接回傳
false
- 使用
every
來檢查每個元素是否相等
- 如果 b 長度與 a 不同,直接回傳
如果 a 與 b 都是物件
- 取得 a 與 b 的 key
- 如果 key 長度不同,直接回傳
false
- 使用
every
來檢查每個 key 是否相等
筆者解答
function isEqual(a, b) {if (a === b) {return true;}if (Array.isArray(a)) {if (a.length !== b.length) {return false;}return a.every((item, idx) => isEqual(item, b[idx]));}if (typeof a === 'object' && typeof b === 'object') {let aKeys = Object.keys(a);let bKeys = Object.keys(b);if (aKeys.length !== bKeys.length) {return false;}return aKeys.every((k) => isEqual(a[k], b[k]));}return false;}
相關題目
如果您喜歡這篇文章,請點擊下方按鈕分享給更多人,這將是對筆者創作的最大支持和鼓勵。