3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 |for循环中if else容易忽视的逻辑错误

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的逻辑,相等则存在,不相等则不存在。我们想当然的认为是这个逻辑,但是这样不对,为什么?

请点击4.1错误写法解析

正确做法

逻辑关系

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) 

验证不存在:

3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 |for循环中if else容易忽视的逻辑错误

验证已存在:

3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 |for循环中if else容易忽视的逻辑错误

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)

判断存在:不添加

3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 |for循环中if else容易忽视的逻辑错误

判断不存在:添加进数组

3.js中判断数组中是否存在某个对象/值,判断数组里的对象是否存在某个值 的五种方法 及应用场景 |for循环中if else容易忽视的逻辑错误

上述几种方式的应用场景

js/vue中添加商品进购物车功能实现

上一篇:JavaScript入门(六)


下一篇:浅拷贝与深拷贝