3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景
一、当数组中的数据是简单类型时:
应用js中的indexof
方法:存在则返回当前项索引,不存在则返回 -1。
var arr=[1,2,3,4]
var str=2
// 如果不等于-1则代表存在
if(arr.indexOf(str) != -1){
console.log('存在!')
}
// 否则不存在
else{
console.log('不存在!')
}
二、当数组中的数据是复杂类型的对象时:
方法1:json化成字符串再用indexOf
因为对象是复杂类型的,得先化成字符串再用indexOf.
注意:indexof 你得确保查找的这个对象与数组内的对象完全一致,对象里每一个键值对的位置都一致,才能说是完全相等的对象。
比如说,这个数组里的对象arr_obj本来就是由obj加进去的,此时obj判断是不是已经加进去了。如果加进去了就不用再加了,这种情况可以适用。
indexof原本并不是用于数组里比较复杂类型的对象,它主要用于简单数据类型。
用法:
//验证条件
if(JSON.stringify(arr).indexOf(JSON.stringify(obj)) == -1){
console.log('该项不存在!')
}else{
console.log('该项存在!')
}
//对象添加进数组后,查找数组中这个对象。
console.log(arr[arr.indexOf(obj)]) //简单类型
console.log(arr[JSON.stringify(arr).indexOf(JSON.stringify(obj))]) //复杂类型
//查找数组中这个对象的某个键 count键
console.log(arr[JSON.stringify(arr).indexOf(JSON.stringify(obj))].count)
应用:
obj={id:1,name:'xiaoming',age:16,count:0}
// obj={id:4,name:'xiaoli',age:17,count:0} //验证不存在
arr=[
{id:1,name:'xiaoming',age:16,count:0},
{id:2,name:"xiaobai",age:19,count:0}
]
if(JSON.stringify(arr).indexOf(JSON.stringify(obj)) == -1){
//数组中不存在该项,把该项添加到数组中
console.log('该项不存在!')
arr.push(obj);
console.log(arr)
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]["id"])
}
}
else {
console.log('该项已存在!');
// 让数组中该项的count++
//查找数组中的某个对象。
// console.log(arr[arr.indexOf(obj)])
// console.log(arr[JSON.stringify(arr).indexOf(JSON.stringify(obj))])
arr[JSON.stringify(arr).indexOf(JSON.stringify(obj))].count++
}
以下验证数组中是否存在某对象的几种方式都是都是一种思路:
判断数组里的对象是否存在某个值
判断数组里的对象是否存在某个值,比如说数组arrtest[0]的id, 与objtest的id做比较,或者拿他们的name作比较,相同就证明存在此对象。
obj={id: 1,name:'xiaoming',age:16}
arr=[
{id: 1,name:"xiaoming",age:16},
{id: 2,name:"xiaobai",age:19}
]
方法2:应用数组 API findIndex
findIndex是es6中新增的方法。返回数组中满足条件的第一个元素的索引。否则返回-1。
和es5中的indexOf相似。
obj={id:1,name:'xiaoming',age:16,count:0}
// obj={id:4,name:'xiaoli',age:17,count:0} //验证不存在
arr=[
{id:1,name:'xiaoming',age:16,count:0},
{id:2,name:"xiaobai",age:19,count:0}
]
objid=obj["id"]
function func1(arr,objid){
var index = arr.findIndex(item => item.id=== objid)
if(index==-1){//说明arr中不存在id为objid的对象
console.log("数组中不存在")
}else{
console.log("数组中存在")
}
}
func1(arr,objid)
方法3:应用数组 API some
some是es6中新增的方法。这个指定了一个状态值result. 通过状态值判定。
// obj={id:1,name:'xiaoming',age:16,count:0} //验证存在
obj={id:4,name:'xiaoli',age:17,count:0} //验证不存在
arr=[
{id:1,name:'xiaoming',age:16,count:0},
{id:2,name:"xiaobai",age:19,count:0}
]
function func1(obj,arr){
let result = arr.some(item =>{ // 这里是判断关键 存在 返回 true result=true
if(item.id===obj.id)
return true
})
if(result){
console.log("数组中该对象已存在")
}else{
console.log("数组中不存在该项")
arr.push(obj)
}
}
func1(obj,arr)
方法4:自己写逻辑
上述都是js封装好的API,我们自己写的话要遍历数组。
自己写也是通过数组的对象里存在某个值和对象的某个值比较,相等则数组里有对象,没有相等的则没有。
方法4.1
for里面两个if语句,通过obj与数组的每一项obj比较,相等则进入第一个if,表示数组里存在obj,break,出for循环,遍历完了没有相等的则进入第二个if,表示数组里不存在这个obj。
这里逻辑上比较容易出错:
应该用 两个if的逻辑,一个if代表相等,另一个代表遍历完了还没有找到相等的。那如何代表都遍历完了还没有相等的呢?下边应用代码有解析。
不能用 if和else的逻辑,相等则存在,不相等则不存在。我们想当然的认为是这个逻辑,但是这样不对,为什么?
正确做法
逻辑关系
for(...){
if(相等){
...
break; //break:跳出循环。在for循环里,如果一个if语句break了,他会不走下边了。跳出for循环。
}
// if(i==arr.length-1)代表遍历完了。
// 为啥代表遍历完了呢?i一直在++,i代表索引,for循环直到最后一个索引arr.length-1,直到最后一个值上边那个if也没有找到相等的,会进入第二个if,表示数据不存在列表里。然后push进这条数据。
if(i==arr.length-1){
...
break;
}
}
应用 :
obj={id:1,name:'xiaoming',age:16,count:0} //验证存在
// obj={id:4,name:'xiaoli',age:17,count:0} //验证不存在
arr=[
{id:1,name:'xiaoming',age:16,count:0},
{id:2,name:"xiaobai",age:19,count:0}
]
function func1(arr,obj){
//1.判断arr是否为空
if(arr.length==0){
// arr为空添加obj
arr.push(obj)
}else{
//2.arr不为空
//判断arr中某对象的id==obj的id,相等则有这条数据
for (var i = 0; i < arr.length; i++) {
if(arr[i]["id"]==obj["id"]){
// 2.1 有这条数据,不添加obj,执行逻辑后,跳出for循环
console.log("数组中已存在这条数据")
arr[i]["count"]++ //更改数组里对象内部 给数组里的对象的键count++
console.log("此对象的count+1:count="+arr[i]["count"])
break;//找到就跳出循环
}
//如果一个obj的id和arr里obj的不相等,则不走上面的if,走这个if
//i是索引值,索引值都等于最后一条数据的索引了,意思是遍历到最后一条数据了。
//obj和arr里的每个对象都比较一遍时还没有找到一样的。说明arr里没obj.
//P.S.arr的最后一条obj数据和obj相等,也会进上面那个if,然后跳出,不会进这里
if(i==arr.length-1){
console.log("数组中不存在这条数据")
//obj加入arr里面
arr.push(obj);
console.log(arr)
break;
}
}
}
}
func1(arr,obj)
验证不存在:
验证已存在:
4.1错误写法
错误写法逻辑关系
for(...){
if(arr[i]["id"]==obj["id"]){//相等
//代表数组里存在
}else{
//代表数组里不存在
}
}
//添加商品进数组。
var goodsid=obj.id
for(){ //
if(goodsid==arr[i].id){ //数组里有这条数据,使count++
count++
}else{ //数组里没有这条数据,push进数组
push进arrlist
}
}
报错信息:
数组里存在这个obj: obj在if和else两种情况都进入了。
数组里存在这个obj: obj在if和else两种情况也都进入了。
不管数组里存在不存在obj, 两种情况都会进入。
很神奇,那这是为啥呢?
错误原因:
if里面arr[i]["id"]==obj["id"]
代表 obj的id值和arr里某个对象的id值相等了,就进入if了。
那else能代表obj在arr里没找到相等的吗?
答案是不能代表。究其原因是else还在for循环里,for循环没有遍历完。
举个例子:
for循环里:
arr [{id:1,,},{id:2,,},{id:3,,},{id:4,,}]
obj {id:1}
在if里面goodsid与挨个他们的id作比较:
如果数组里存在该对象:
如果goodsid=1,for循环里第一个id也是1,这条就进if了,但是for还没有循环完,goodid会继续与id=2,3,4作比较,
结果是goodsid=1和arr里第二个obj,id=2的不匹配,又进入else了。
如果goodsid=2, for循环开始,它和id=1作比较,两者不相等,直接进else,它认定数组里没有这条数据,它直接被else的逻辑push进数组了,但是它还没和其他的做比较呢,后面有和它相同的id=2的数据,此时for循环还在继续,等循环第二遍找到数组里id=2的obj,它俩相等了,它又进if情况了。两种情况又都进入了。
所以说得把每一条数据都比较一遍,才可以认定数组里有没有这条数据。else不能代表数组里没有这条数据了。
如果数组里不存在该对象:
比如说obj的id=5,数组没有id为5的对象。
arr [{id:1,,},{id:2,,},{id:3,,},{id:4,,}]
obj {id:5,,}
goodid=obj.id
对象进入for循环,首先这个对象不会进if,因为和id=1比较它不相等啊,它会进else情况,else情况直接把它push进数组了,此时arr里面已经有id为5的对象了,因为if,else都在for循环里,得等for循环执行完了才能出来,当for循环循环到第五遍时,检验到arr里obj的id和这个相等了,都是5,它会进if情况。
所以,这也是两个情况都进入了。
综上所述,就是for循环没有走完,else不能代表所有项的锅。
方法4.2 标识符
标识符的方法大家都很熟悉,先看一个小例子帮助理解。
质数的判断方法
//输出100以内的质数 思路:一个数字只能被1和它本身整除
for(var i=2;i<=100;i++){
var bol=false;
for(j=2;j<=100;j++){
if(i!=j&&i%j==0){//合数 都变成true
bol=true;
}
}for循环完
if(bol==false){//for循环完了后,剩下的false都是质数
console.log(i);
}
}
应用:
// obj={id:1,name:'xiaoming',age:16,count:0} //验证存在
obj={id:4,name:'xiaoli',age:17,count:0} //验证不存在
arr=[
{id:1,name:'xiaoming',age:16,count:0},
{id:2,name:"xiaobai",age:19,count:0}
]
function func1(arr,obj){
var ischecked=false
//1.判断arr是否为空
if(arr.length==0){
// arr为空添加obj
arr.push(obj)
}else{
//2.arr不为空 判断arr中某对象的id==obj的id,相等则有这条数据
for (var i = 0; i < arr.length; i++) {
if(arr[i]["id"]==obj["id"]){
// 2.1 有这条数据,不添加obj,执行逻辑后,
console.log("数组里有这条,不添加,count++")
arr[i]["count"]++ //更改数组里对象内部 给数组里的对象的键count++
console.log("此对象的count+1:count="+arr[i]["count"])
//状态值改成true
ischecked=true
}
}//for循环完
// 判断状态值即可
if(ischecked==false){//判断相等是双==
console.log("数组里没有这条,添加进数组")
//obj加入arr里面
arr.push(obj);
console.log(arr)
}
}
}
func1(arr,obj)
判断存在:不添加
判断不存在:添加进数组