JS短文 | 如何在数组中验证是否含某值
作者:Dmitri Pavlutin
原文:Checking if an Array Contains a Value in JavaScript
字数:1000 字 (非直译)
阅读: 5 分钟
在一个数组中,如果给定一个值,让你判断数组中是否存在相同的值,你会怎么做?想必你会给出不少方法,因为JS提供了不少方法,让我们来使用。
虽然在数组中查找指定的数字或字符串相对容易,但是查找对象就稍微复杂一些。
在本篇文章,你将学习到如何使用更现代的方法,在数组中查找特定的值或对象。
一、查找是否存在指定的值
所谓指定的值,就是查找类似字符串、数字、布尔等这些类型的值。
最简单的方法就是使用ES2015提供的新方法array.includes(),其方法如下:
const hasValue = array.includes(value[, fromIndex]);
第一个参数就是指定要查找的值,第二个参数可选,其含义是从指定的索引位置开始查找。最终返回布尔值来判断指定的数值是否查找到。
接下来,我们来定义一个数组,查找其是否含有 'hi' 和 'hey' 这两个字符串,示例代码如下:
const greetings = ['hi', 'hello'];
greetings.includes('hi'); // => true
greetings.includes('hey'); // => false
1.1 、从指定的索引开始查找
此方法接受第二个参数,从指定的索引开始查找,这个参数是可选的,接下来,如下段代码所示,从索引 1 处开始查找给定的值,示例代码如下:
const letters = ['a', 'b', 'c', 'd'];
letters.includes('c', 1); // => true
letters.includes('a', 1); // => false
从上述代码我们可以看出,从数组索引1处开始查找,我们找到了c。但是由于 a 在数组索引0处,所以未找到。
二、查找指定的对象object是否包含
在数组中查找指定的对象稍微复杂些,我们还是通过代码来进行描述。
如果通过数组索引赋值对象变量的化,array.includes() 也能轻松完成,如下段代码所示:
const greetings = [{ message: 'hi' }, { message: 'hello' }];
const toSearch = greetings[0];
greetings.includes(toSearch); // => true
由上述代码可以看出,通过数组索引赋值对象变量,相当于引用,可以轻松完成查找,但是在实际应用中,我们并不是这么查找对象的,而是通过如下方式进行直接赋值查找,如下段代码所示:
const greetings = [{ message: 'hi' }, { message: 'hello' }];
const toSearch = { message: 'hi' };
greetings.includes(toSearch); // => false
运行上述代码,将返回false,由于数组不包含对象变量的引用,因此查找不到。那么,我们来如何确定数组对象中含有指定的对象呢,我们需要定一个方法,先判断两个对象是否一致,然后结合 array.some()方法来进行迭代数组实现查找指定的对象。
首先我们先定义一个方法 shallowEqual 来判断对象是否一致:
function shallowEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (let key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}
return true;
}
上述代码比较简单,就不过多解释,就是先判断属性值长度是否一致,然后在逐一判断对应属性的值是否一致。
接下来,我们来验证上述代码,定义如下三个对象变量,然后来判断后两个对象是否和第一个对象的内容是否一致:
const hi = { message: 'hi' };
const hiCopy = { message: 'hi' };
const hello = { message: 'hello' };
shallowEqual(hi, hiCopy); // => true
shallowEqual(hi, hello); // => false
运行上述代码,符合我们的预期,接下来我们可以使用 array.some(callback) 迭代数组,调用上述我们定义的 shallowEqual方法,示例代码如下:
const greetings = [{ message: 'hi' }, { message: 'hello' }];
const toSearch = { message: 'hi' };
greetings.some(item => shallowEqual(item, toSearch)); // => true
some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试,如果找到就返回。
如果要查找的对象是嵌套对象,可以使用如下deepEqual方法或使用lodash函数库的_.isEqual(object1, object2)方法。
function deepEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (const key of keys1) {
const val1 = object1[key];
const val2 = object2[key];
const areObjects = isObject(val1) && isObject(val2);
if (
areObjects && !deepEqual(val1, val2) || !areObjects && val1 !== val2
) {
return false;
}
}
return true;
}
function isObject(object) {
return object != null && typeof object === 'object';
}
三、总结
今天的文章就到这里,如果我们要在数组中查找简单的值,我们可以使用 array.includes(value) 方法,如果要在数组中查找对象,我们需要先定义对象比较的方法,然后通过array.some(callback)的迭代函数的方法进行判断:
array.some(item => shallowEqual(item, value));
注:本篇文章,并不是唯一数组查找指定值的方法,在过去很长的一段时间里,我们会常用 array.indexOf(value) !== -1 来进行判断,理解起来比较绕,不如 array.includes(value) 更符合我们人的思维。
你有什么好的方法查找数组中指定的值,欢迎大家在留言区进行讨论,感谢你的阅读。