给定两个数组,判断两数组内容是否相等。
例:
[1, 2, 3] 和 [1, 3, 2] // true
[1, 2, 3] 和 [1, 2, 4] // false
思考几秒:有了😀😀
const arr1 = ["apple", "banana", 1]
const arr2 = ["apple", 1, "banana"]
function fn(arr1, arr2) {
// Arrary.some: 有一项不满足 返回false
// Arrary.indexOf: 查到返回下标,查不到返回 -1
if (arr1.length !== arr2.length) {
return false;
}
return !arr1.some(item => arr2.indexOf(item)===-1)
}
fn(arr1,arr2) // true
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() 是使用的严格相等算法 => NaN值永远不相等
Array.prototype.includes() 是使用的零值相等算法 => NaN值视作相等
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 确实可以判断NaN了,如果数组元素有重复呢?
// 重复的元素都是banana
const array1 = ["apple", "banana", "cherry", "banana"];
const array2 = ["banana", "apple", "banana", "cherry"];
// 或者
// 一个重复的元素是banana, 一个是apple
const array1 = ["apple", "banana", "cherry", "banana"];
const array2 = ["banana", "apple", "apple", "cherry"];
由上可知:这种行不通,接下来看看是否能从给数组元素添加标识入手
这个简单:数组 元素重复 转换成val1, val2
function areArraysContentEqual(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
// 重复数组元素 加1、2、3
const countArr1 = updateArray(arr1)
const countArr2 = updateArray(arr2)
/**
*
* @param {*} arr 数组 元素重复 转换成val1, val2
* @returns
*/
function updateArray(arr) {
const countMap = new Map();
const updatedArr = [];
for (const item of arr) {
if (!countMap.has(item)) {
// 如果元素是第一次出现,直接添加到结果数组
countMap.set(item, 0);
updatedArr.push(item);
} else {
// 如果元素已经出现过,添加带有编号的新元素到结果数组
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
// 其实这种存在漏洞的
const array3 = ["apple", "banana", "cherry", "banana", 1, '1', '1' ];
const array4 = ["banana", "apple", "banana", "cherry", '1', 1, 1];
// 应该是false
areArraysContentEqual(array3, array4) // true
因为把判断的 转为了字符串 updatedArr.push(${item}${count}
) 所以出问题了
function areArraysContentEqual(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
// 创建计数对象,用于记录每个元素在数组中的出现次数
const countMap1 = count(arr1)
const countMap2 = count(arr2)
// 统计数组中的元素出现次数
function count(arr = []) {
const resMap = new Map();
for (const item of arr) {
resMap.set(item, (resMap.get(item) || 0) + 1);
}
return resMap
}
// 检查计数对象是否相等
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
这样就不需要俩个对象了,而且第二个遍历的时候如果找不到这个值的话也可以直接退出了
function areArraysContentEqual3(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
const countMap = new Map();
// 计数第一个数组的元素
for (const item of arr1) {
countMap.set(item, (countMap.get(item) || 0) + 1);
}
// 比较第二个数组与计数
for (const item of arr2) {
const val = countMap.get(item);
if (val === undefined || val <= 0) {
return false;
}
countMap.set(item, val - 1);
}
return true;
}
遍历第一个数组,在第二个数组找到就删除第二个数组中对应的元素,没有找到直接不等,最后再判断一下第二个数组的长度即可。实际使用中一般不直接操作原数组,浅复制一下就好
可能没有前几个性能好,但是想法还是很好的点赞~
function areArraysContentEqual2(arr1=[], arr2=[]) {
arr2 = [...arr2]
if (arr1.length !== arr2.length) {
return false;
}
arr1.some(item => {
// 找到元素在第二个数组中的位置
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
}
这个题需要注意:
如果本文对你有收获,麻烦动动发财的小手,点点关注、点点赞!!!👻👻👻
因为收藏===会了
关于本文
作者:程序员小易
链接:https://juejin.cn/post/7290786959441117243
看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness#%E9%9B%B6%E5%80%BC%E7%9B%B8%E7%AD%89
欢迎长按图片加好友
,我会第一时间和你分享前端行业趋势
,面试资源
,学习途径
等等。
添加好友备注【进阶学习】拉你进技术交流群
关注公众号后,在首页:
面试题
,获取最新大厂面试资料。简历
,获取 3200 套 简历模板。React实战
,获取 React 最新实战教程。Vue实战
,获取 Vue 最新实战教程。ts
,获取 TypeScript 精讲课程。vite
,获取 Vite 精讲课程。uniapp
,获取 uniapp 精讲课程。js书籍
,获取 js 进阶 必看书籍。Node
,获取 Nodejs+koa2 实战教程。数据结构算法
,获取数据结构算法教程。架构师
,获取 架构师学习资源教程。关注获取