這里給大家分享我在網(wǎng)上總結(jié)出來(lái)的一些知識(shí),希望對(duì)大家有所幫助
題目
給定兩個(gè)數(shù)組,判斷兩數(shù)組內(nèi)容是否相等。
- 不使用排序
- 不考慮元素位置
例:
[1, 2, 3] 和 [1, 3, 2] // true [1, 2, 3] 和 [1, 2, 4] // false
思考幾秒:有了????
1. 直接遍歷?
- 直接遍歷第一個(gè)數(shù)組,并判斷是否存在于在第二個(gè)數(shù)組中
- 求差集, 如果差集數(shù)組有長(zhǎng)度,也說(shuō)明兩數(shù)組不等(個(gè)人感覺比上面的麻煩就不舉例了)
const arr1 = ["apple", "banana", 1] const arr2 = ["apple", 1, "banana"] function fn(arr1, arr2) { // Arrary.some: 有一項(xiàng)不滿足 返回false // Arrary.indexOf: 查到返回下標(biāo),查不到返回 -1 if (arr1.length !== arr2.length) { return false; } return !arr1.some(item => arr2.indexOf(item)===-1) } fn(arr1,arr2) // true
- 細(xì)心的小伙伴就會(huì)發(fā)現(xiàn):NaN 會(huì)有問(wèn)題
const arr1 = ["apple", "banana", NaN] const arr2 = ["apple", NaN, "banana"] function fn(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } return !arr1.some(item => arr2.indexOf(item)===-1) } fn(arr1,arr2) // false
Arrary.prototype.indexOf() 是使用的嚴(yán)格相等算法 => NaN值永遠(yuǎn)不相等
Array.prototype.includes() 是使用的零值相等算法 => NaN值視作相等
- 嚴(yán)格相等算法: 與 === 運(yùn)算符使用的算法相同
- 零值相等不作為 JavaScript API 公開, -0和0 視作相等,NaN值視作相等,具體參考mdn文檔:
- 使用includes
const arr1 = ["apple", "banana", NaN] const arr2 = ["apple", NaN, "banana"] function fn(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } return !arr1.some(item => !arr2.includes(item)) } fn(arr1,arr2) // true
使用includes 確實(shí)可以判斷NaN了,如果數(shù)組元素有重復(fù)呢?
// 重復(fù)的元素都是banana const array1 = ["apple", "banana", "cherry", "banana"]; const array2 = ["banana", "apple", "banana", "cherry"]; // 或者 // 一個(gè)重復(fù)的元素是banana, 一個(gè)是apple const array1 = ["apple", "banana", "cherry", "banana"]; const array2 = ["banana", "apple", "apple", "cherry"];
由上可知:這種行不通,接下來(lái)看看是否能從給數(shù)組元素添加標(biāo)識(shí)入手
2. 把重復(fù)元素標(biāo)識(shí)編號(hào)?
這個(gè)簡(jiǎn)單:數(shù)組 元素重復(fù) 轉(zhuǎn)換成val1, val2
function areArraysContentEqual(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } // 重復(fù)數(shù)組元素 加1、2、3 const countArr1 = updateArray(arr1) const countArr2 = updateArray(arr2) /** * * @param {*} arr 數(shù)組 元素重復(fù) 轉(zhuǎn)換成val1, val2 * @returns */ function updateArray(arr) { const countMap = new Map(); const updatedArr = []; for (const item of arr) { if (!countMap.has(item)) { // 如果元素是第一次出現(xiàn),直接添加到結(jié)果數(shù)組 countMap.set(item, 0); updatedArr.push(item); } else { // 如果元素已經(jīng)出現(xiàn)過(guò),添加帶有編號(hào)的新元素到結(jié)果數(shù)組 const count = countMap.get(item) + 1; countMap.set(item, count); updatedArr.push(`${item}${count}`); } } return updatedArr; } const flag = countArr1.some(item => !countArr2.includes(item)) return !flag } const array1 = ["apple", "banana", "cherry", "banana"]; const array2 = ["banana", "apple", "banana", "cherry"]; areArraysContentEqual(array1, array2) // true // 其實(shí)這種存在漏洞的 const array3 = ["apple", "banana", "cherry", "banana", 1, '1', '1' ]; const array4 = ["banana", "apple", "banana", "cherry", '1', 1, 1]; // 應(yīng)該是false areArraysContentEqual(array3, array4) // true
因?yàn)榘雅袛嗟?轉(zhuǎn)為了字符串 updatedArr.push(${item}${count}
) 所以出問(wèn)題了
3. 統(tǒng)計(jì)元素次數(shù)(最終方案)?
function areArraysContentEqual(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } // 創(chuàng)建計(jì)數(shù)對(duì)象,用于記錄每個(gè)元素在數(shù)組中的出現(xiàn)次數(shù) const countMap1 = count(arr1) const countMap2 = count(arr2) // 統(tǒng)計(jì)數(shù)組中的元素出現(xiàn)次數(shù) function count(arr = []) { const resMap = new Map(); for (const item of arr) { resMap.set(item, (resMap.get(item) || 0) + 1); } return resMap } // 檢查計(jì)數(shù)對(duì)象是否相等 for (const [key, count] of countMap1) { if (countMap2.get(key) !== count) { return false; } } return true; } const array1 = ["apple", "banana", "cherry", "banana", 1, '1', '11', 11]; const array2 = ["banana", "apple", "banana", "cherry", '1', 1, '11', 11]; areArraysContentEqual(array1, array2) // true
4. 評(píng)論區(qū)大佬方案(+1、-1)??
- 只需要一個(gè)對(duì)象
- 遍歷第一個(gè)數(shù)組就 +1
- 遍歷第二個(gè)數(shù)組就 - 1
- 最后遍歷對(duì)象,只要不是都是 0 就等于不匹配
這樣就不需要倆個(gè)對(duì)象了,而且第二個(gè)遍歷的時(shí)候如果找不到這個(gè)值的話也可以直接退出了
function areArraysContentEqual3(arr1, arr2) { if (arr1.length !== arr2.length) { return false; } const countMap = new Map(); // 計(jì)數(shù)第一個(gè)數(shù)組的元素 for (const item of arr1) { countMap.set(item, (countMap.get(item) || 0) + 1); } // 比較第二個(gè)數(shù)組與計(jì)數(shù) for (const item of arr2) { const val = countMap.get(item); if (val === undefined || val <= 0) { return false; } countMap.set(item, val - 1); } return true; }
5. 評(píng)論區(qū)大佬方案(操作第二個(gè)數(shù)組)??
遍歷第一個(gè)數(shù)組,在第二個(gè)數(shù)組找到就刪除第二個(gè)數(shù)組中對(duì)應(yīng)的元素,沒有找到直接不等,最后再判斷一下第二個(gè)數(shù)組的長(zhǎng)度即可。實(shí)際使用中一般不直接操作原數(shù)組,淺復(fù)制一下就好
可能沒有前幾個(gè)性能好,但是想法還是很好的點(diǎn)贊~
function areArraysContentEqual2(arr1=[], arr2=[]) { arr2 = [...arr2] if (arr1.length !== arr2.length) { return false; } arr1.some(item => { // 找到元素在第二個(gè)數(shù)組中的位置 const index = arr2.findIndex(item1 => { if (isNaN(item) && isNaN(item1)) { return true } return item ===item1 }) if (index !== -1 ) { arr2.splice(index, 1) } }) return !arr2.length }
注意事項(xiàng)
這個(gè)題需要注意:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-710882.html
- 先判斷長(zhǎng)度,長(zhǎng)度不等 必然不等
- 元素可重復(fù)
- 邊界情況考慮
- '1' 和 1 (Object的key是字符串, Map的key沒有限制)
- NaN
- null undefined
本文轉(zhuǎn)載于:
https://juejin.cn/post/7290786959441117243
如果對(duì)您有所幫助,歡迎您點(diǎn)個(gè)關(guān)注,我會(huì)定時(shí)更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進(jìn)步。
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-710882.html
到了這里,關(guān)于記錄--如何判斷兩個(gè)數(shù)組的內(nèi)容是否相等的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!