文章目录
day17
01数组去重的方法
①for循环去重
1)把第一个拿出来,和后面所有的元素进行挨个比较
var arr=[11,11,11,22,23,24,24,25,126];
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]==arr[j])
//将元素重复的元素删除
arr.splice(j,1)
}
}
console.log(arr)
结果发现出错了 , 这是初学者常犯的一个错误
原因是splice的操作改变了数组的长度
//可以使用断点调试的方法 进行检查
i=0 j=1
arr[i]==arr[j]//arr=[11,11,22,23,24,24,25,126]
i=1 j=2
i的执行是没问题的 关键在于j
a[1]==11 a[2]==22
这里就出现问题了 , 实际上我们想要第二个11和第三个11进行比较 这在初始数组里是arr[1]和arr[2], 但是由于数组长度减少一个 , 所以要让数组元素减少后的数组在进行内层循环的时候j–, j 会回到当前删除位置, 检查已经修改位置的元素
正确代码:
var arr=[11,11,11,22,23,24,24,25,126];
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length-1;j++){
//小于长度减一是因为不让j超过数组
if(arr[i]==arr[j])
//将元素重复的元素删除
arr.splice(j,1)
j--
}
}
console.log(arr)
2)相邻两个进行比较
var arr=[11,11,11,22,23,24,24,25,126];
for(var i=0;i<arr.length-1;i++){
if(arr[i]==arr[i+1]){
arr.splice(i,1)
i--
}
}
console.log(arr)
3)使用 for 循环和 indexOf
你可以使用传统的 for 循环和 indexOf 方法手动实现去重。
思路是: 准备一个新数组, 遍历原来的数组, 如果新数组中没有这个元素,(这用newarr.indexOf(arr[i])===-1) 那就存入新数组, 如果发现新数组里已经有某个元素, 那就不会再存入新数组, 这种方式和前面两个的不同是不改变原来的数组
var arr = [11, 11, 22, 23, 24, 24, 25, 126];
var uniqueArr = [];
for (var i = 0; i < arr.length; i++) {
if (uniqueArr.indexOf(arr[i]) === -1) {
uniqueArr.push(arr[i]);
}
}
console.log(uniqueArr); // 输出: [11, 22, 23, 24, 25, 126]
②filter + indexOf
var arr = [10, 20, 10, 30, 40, 20, 50];
var arr = [10, 20, 10, 30, 40, 20, 50];
var newarr = arr.filter(function (element, index, arr) {
return arr.indexOf(element) === index;
});
//查找第一个元素 10 ,
//indexOf(10) 返回 0,因为 10 第一次出现在索引 0。
//index 也是 0,所以 return 0 === 0 返回 true,10 被保留
- filter 方法会遍历每个元素。
- indexOf(value) 返回数组中第一个匹配到的元素索引,只有当前元素是该元素第一次出- 现时,indexOf 返回的索引才与当前索引 index 相等,才保留该元素。
- 优点:
可定制的去重逻辑。
适用于不支持 Set 的环境。 - 缺点
性能相对较差,因为 indexOf 会遍历数组
③使用 reduce 方法
reduce 方法通过累积的方式生成新的数组,结合 includes 可以实现去重。
var arr = [11, 11, 22, 23, 24, 24, 25, 126];
var uniqueArr = arr.reduce((acc, value) => {
if (!acc.includes(value)) {
acc.push(value);
}
return acc;
}, []);
console.log(uniqueArr); // 输出: [11, 22, 23, 24, 25, 126]
- 解释:
reduce 会遍历数组,并将不重复的元素添加到累积器 acc 中。
includes 检查元素是否已经存在于累积器中,只有没有出现过的元素才会被添加。 - 优点:
灵活,适合各种去重逻辑。
适用于对元素进行其他操作的去重(如排序、变换等)。 - 缺点:
性能较差,因为 includes 会遍历累积器数组。
④使用 Set
for 循环和 indexOf去重方法遍历了数组, 在数组很大的时候并不高效, 如果使用set, 可以很大的降低查找和插入的时间复杂度 . 同时可以简化代码 .
Set 是一个 ES6 引入的数据结构,它类似于数组,但其中的元素是唯一的,因此可以利用 Set 来去重数组。
示例:
var arr = [11, 11, 22, 23, 24, 24, 25, 126];
var uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // 输出: [11, 22, 23, 24, 25, 126]
- 解释:
new Set(arr) 会创建一个 Set 集合,自动去除数组中的重复元素。
使用扩展运算符 […Set] 将 Set 转换回数组。 - 优点:
简洁、易于理解。=性能相对较好,尤其是处理较大数组时。 - 缺点:
需要 ES6 环境支持。
⑤使用 Map 或 Object(适用于对象数组)
如果你去重的数组包含对象(比如具有相同某个属性的对象),可以使用 Map 或 Object 来去重。
var arr = [
{ id: 1, name: 'Alice' },
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
var uniqueArr = Array.from(new Map(arr.map(item => [item.id, item])).values());
console.log(uniqueArr);
// 输出: [
// { id: 1, name: 'Alice' },
// { id: 2, name: 'Bob' },
// { id: 3, name: 'Charlie' }
// ]
- 解释:
arr.map(item => [item.id, item]) 将数组转换为 [key, value] 的形式,key 为对象的 id,value 为对象本身。
new Map(…) 会根据 id 去重(Map 键是唯一的)。 - 使用 Array.from(…values()) 将去重后的 Map 转换为数组。从类数组对象(array-like object)或可迭代对象(iterable object)创建一个新的数组实例。
- 优点:
对于对象数组,基于某个属性进行去重非常方便。
性能比 indexOf 或 includes 更好。
02字符串常见方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let str = "abcdefg";
//字符串里的方法对原字符串没有影响,我们要用的话,主要是返回值
//charAt() 取到某个索引位上的字符
console.log(str.charAt(1)); //"b"
//indexOf() 取到某个字符(子串)在字符串中的索引,没有得到-1
console.log(str.indexOf("d")); //3
//substring()第1个参数表示截取的起始索引,第2个参数表示结束索引,不含第2个参数对应的字符 ,两个谁打谁小无所谓,默认以小值作为起始索引
//slice() 第1个参数表示截取的起始索引,第2个参数表示结束索引,不含第2个参数对应的字符
console.log(str.substring(1, 3)); //"bc"
console.log(str.substring(3, 1)); //"bc"
console.log(str.slice(1, 3)); //"bc"
console.log(str.slice(3, 1)); //""
//substr()第1个参数表示截取的起始索引,第2个参数表示截取的字符个数
console.log(str.substr(2, 2)); //"cd"
//split() 将字符串以指定分隔符(参数)分割成数组,分隔符不作为数组元素
console.log(str.split("")); //
console.log(str.split("d")); //["abc","efg"]
let str1 = "ab|de|g";
console.log(str1.split("|"));
//replace(已存在的字符,新的字符)
let str2 = "abctmddeftmd";
//console.log(str2.replace("tmd", "***")); //只替换第一个
console.log(str2.replaceAll("tmd", "XXX")); //替换所有
let str3 = "王小明和范小明";
console.log(str3.replace("和", "xx"));
//concat() 合并
console.log(str2.concat(str3, "a"));
//trim() 去掉首尾空格
let str4 = " abc ";
console.log(str4);
console.log(str4.trim());
//toUpperCase() //大写
let str5 = "Abc";
console.log(str5.toUpperCase()); //"ABC"
//toLowerCase() //小写
console.log(str5.toLowerCase()); //"abc"
</script>
</body>
</html>
03字符串小案例-敏感词过滤
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box
{
height: 200px;
width: 200px;
border: 1px solid orange;
}
</style>
</head>
<body>
<input type="text" id="txt">
<button id="btn">submit
</button>
<div id="box"></div>
</body>
</html>
<script>
var arr=["cnm","sb","nnd"]
btn.onclick=function(){
var val=txt.value
arr.forEach((v)=>{
val=val.replaceAll(v,"***")//replaceAll返回的是新的=字符串 , searchValue:可以是一个字符串或正则表达式,表示需要被替换的部
//replaceValue:表示用来替换 searchValue 的内容,可以是字符串或一个函数
})
box.innerHTML= val;
}
</script>
ASCII码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//编码规范 ASCII
//charCodeAt() //某个索引位上的字符的码值
let str = "Abc";
console.log(str.charCodeAt(0));
console.log(str.charCodeAt(1));
//fromCharCode() //通过码值得到字符
console.log(String.fromCharCode(65)); //"A"
console.log(String.fromCharCode(98)); //"b"
</script>
</body>
</html>