JavaScript的in操作符(“如何判断某值是否数组中的元素”?)在编写JavaScript时,遇到⼀个常见的问题“如何判断某值是否数组中的元素”?这让我想起了PHP中的in_array()函数和Python中in 操作
符。但JavaScript似乎没有内置类似的函数,⽽其in 操作符的作⽤也有点不同。通过查询相关的资料,我发现JavaScript的in 操作符还是挺有⽤的。
⼀、问题
让我想到in 操作符,正是因为这样⼀个问题:“如何判断某值是否数组中的元素”?
在PHP中,您可能会这样来处理:
$os = array("Mac", "NT", "Irix", "Linux");javascript数组对象
if (in_array("Irix", $os)) {
echo "Got Irix";
}
Python 中,可能会是这样:
val = 17
if val in [1,4,5,7,12,14,17,20,34]: print "yes"
那JavaScript中该如何操作呢?先来看看in 操作符的说明。
⼆、in 操作符
现在写JavaScript时,我喜欢参考两个地⽅:MDC 的和 W3Schools 的。
从,可到in Operator的说明。可见,JavaScript中的in 操作符是对Object(对象)操作的,并不是针对数组。
1、简单⽤法
in 的右边必须是对象变量,例如:
var mycar = {make: "Honda", model: "Accord", year: 1998};
if ( "make" in mycar ) document.write('true');
else document.write('false'); // 显⽰true
2、错误的⽤法
若我们把in ⽤于数组的判断时,会产⽣错误结果:
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
if ( "oak" in trees ) document.write('true');
else document.write('false'); //显⽰false
反过来,我们把trees数组看成⼀个对象,然后判断对象中的元素,例如:
if ( 0 in trees ) document.write('true');
else document.write('false'); //显⽰true
document.write(trees.length); //显⽰trees数组对象的length属性值:5
if ( 'length' in trees ) document.write('true');
else document.write('false'); //显⽰true,因为length是trees数组对象的属性
三、对数组判断的正确⽅法
虽然in 直接在⽤于判断数组时会产⽣错误结果,但也不是没有办法可以避免的。合适地使⽤in 操作符反⽽可以带来便利。
1、通过循环来解决问题
其实,这是处理“如何判断某值是否数组中的元素”问题的最基本⽅法:
function in_array(searchString,array) {
for (i=0;i<array.length;i++) {
if ( searchString == array[i] ) return true;
}
return false;
}
if ( in_array('oak',trees) ) document.write('true'); //显⽰true
else document.write('false');
2、合适的利⽤in 操作符
既然我们知道in 可以⽤于判断对象的属性值,那么,同样的,我们可以把数组⼀⼀映射到对象的属性,然后再⽤in 判断。以下代码参考⾃:。
function oc(a)
{
var o = {}; //相当于var o = new Object();
for(var i=0;i<a.length;i++)
{
o[a[i]]=''; //注意该写法,不能写成o.a[i]
}
return o;
}
if ( 'oak' in oc(trees) ) document.write('true'); //显⽰true
else document.write('false');
o = oc(trees);
if ( o.oak != 'undefined' ) document.write('true'); //显⽰true
else document.write('false'); //true
if ( o['oak'] != 'undefined' ) document.write('true'); //显⽰true
else document.write('false'); //true
这⾥,oc 函数把⼀个数组转换成对象,并把数组的元素作为对象的属性(值为空字符串),然后利⽤了in 操作符判断。
※注意:平时obj.key和obj['key']可以互通,但在for(;;)和for(in)语句中,对象属性的写法是obj['key'],⽽不是obj.key。
3、巧⽤in 操作符
除了数组情况下可借⽤in 操作符外,我们还可以利⽤in 的特性来简化if 语句在多个“或”条件情况时的写法。
例如,下⾯⼀句:
if ( foo == 'bar' || foo == 'foobar' || foo == 'foo' )
{
//...
}
就可以写成:
if ( foo in { 'bar':'', 'foobar':'', 'foo':'' } )
{
//...
}
判断结果相同。
四、注意事项
使⽤in 操作符时,除了⼩⼼区分数组与对象的区别外,还需要注意:
1、in ⾯向的必须是对象
例如,下⾯对字符串的判断中:
var color1 = new String("green");
"length" in color1 // returns true
var color2 = "coral";
"length" in color2 // generates an error (color is not a String object)
因为JavaScript与Python不同,字符串并不能直接就处理为字符串对象。FireFox 中会报“invalid 'in' operand color2”,IE 中会报“缺少对象”。
2、对象属性被删除(deleted)或未定义(undefined)的判断结果是不同的
⽤delete删除对象的属性值:
var mycar = {make: "Honda", model: "Accord", year: 1998};
delete mycar.make;
"make" in mycar; // returns false
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
3 in trees; // returns false
把对象属性值设置为undefined:
var mycar = {make: "Honda", model: "Accord", year: 1998};
mycar.make = undefined;
"make" in mycar; // returns true
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
trees[3] = undefined;
3 in trees; // returns true
3、关联数组
既然数组可以转换为对象,我们就可以把JavaScript的对象看成是“关联数组”(类似Python中的字典、Perl中的Hash),⽽普通数组元素就对应对象的属性(值为空)的情况。
var oneArray=new Array();
oneArray["firstKey"]="firstValue";
oneArray["secondKey"]="secondValue";
var oneObject={};
oneObject.firstKey="firstValue";
oneObject.secondKey="secondValue";
for ( key in oneArray ) {
document.write(key+'=>'+oneArray[key]);
}
for ( key in oneObject ) {
document.write(key+'=>'+oneObject[key]);
}
这样,有以下优势:
引⽤
a、我们就可以⾮常⽅便的利⽤in 来判断元素是否在对象中;
b、对象中检索属性,例如:o['oak'],其时间复杂度为O(1),⽽要在数组中⼀个元素,时间复杂度为O(n)。
不过,也不说所有的数组都可以⽤对象来代替的。⾄少,必须要求数组中元素是唯⼀的。
例如,下⾯的数组:
var trees = new Array("redwood", "bay", "cedar", "oak", "maple","oak");
因为"oak"元素重复了,就不能直接等转换为某个对象。
4、效率问题
根据介绍,见:。其中提出:
集合的遍历效率(从⾼到低)为:var value = obj[key]; > for ( ; ; ) > for ( in )。
所以说,如果数组能⽤对象代替(值唯⼀),应⾸选对象形式。当遇到“判断某值是否数组中的元素”时,直接判断该值obj.key ==
'undefined',或if( 'key' in obj )即可。否则,⽤for(;;)⽅式判断吧。
(对象没有length,不能⽤for(;;)循环,只能⽤for(in))
另外,在:,也提到了⼀个遍历数组的效率问题。其中提出,循环前,把数组的length先赋值个某变量后,循环时直接调⽤,这样效率会更⾼。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论