Javascript newbie here -
我有以下数组:
var group = ({
one: value1,
two: value2,
three: value3
});
我想检查数组“group”是否为“groupsArray”的一部分,如果没有则添加它,如果有则将其删除。
var groupLocate = $.inArray(group, groupsArray);
if(groupLocate ==-1){
groupsArray.push(group);
} else {
groupsArray.splice($.inArray(group, groupsArray),1);
}
此方法适用于单值数组。不幸的是,在这种情况下我无法使用三个键和值来工作,因为groupLocate总是返回-1。
我做错了什么?
感谢。
答案 0 :(得分:2)
首先,它有助于理解为什么$.inArray()
不起作用。让我们尝试一个更简单的案例。将其粘贴到浏览器中的JavaScript控制台上,加载jQuery的页面(例如我们所在的页面)并运行它:
var object = { a: 1 };
var array = [ { a: 1 } ];
console.log( '$.inArray: ', $.inArray( object, array ) );
(注意术语:您的group
变量是Object,而不是Array。)
现在看起来object
在数组中,对吗?为什么打印-1
呢?试试这个:
console.log( object );
console.log( array[0] );
他们看起来一样。怎么样:
console.log( '== or === works? ', object == array[0], object === array[0] );
甚至更简单:
console.log( 'Does {a:1} == {a:1}? ', {a:1} == {a:1} );
console.log( 'What about {} == {}? ', {} == {} );
全部打印false
!
这是因为碰巧具有相同内容的两个对象仍然是两个独立的对象,当您使用==
或===
来比较两个对象时,您实际上正在测试它们是否都是引用同一个对象。两个不同的对象永远不会相等,即使它们包含完全相同的内容。
$.inArray()
就像使用===
运算符来比较两个对象一样 - 它不会在数组中找到对象,除非它是相同的对象,而不仅仅是具有相同内容的对象。
了解这一点,是否表明有任何可能的方法来解决问题?有几种方法可以编写自己的代码来搜索数组中的对象,或者您可能会发现使用诸如Underscore.js这样的库有用,它有许多有用的数组和对象方法。
例如,您可以使用_.findWhere( groupsArray, group )
查找第一个匹配项 - 但需要注意的是它只会比较group
对象中的属性。例如,如果group
为{a:1}
,则它会匹配groupsArray
数组中{a:1,b:2}
的对象。
如果您需要完全匹配,可以结合使用Underscore的_.find()
和_.isEqual()
方法:
var index = _.find( groupsArray, function( element ) {
return _.isEqual( element, group );
});
现在最后要注意的一件事。将group
对象推送到groupsArray
数组的代码 - 您知道推送实际的group
对象本身。它不会在数组中复制它,它是对同一个对象的引用。 (具有讽刺意味的是,这意味着在数组中查找group
的原始代码实际上可以用于您自己将相同的group
对象推送到数组上的情况。)
如果要确保groupsArray
中的元素都是它们自己的独立对象,而不是对代码中浮动的另一个对象的引用,则可以使用另一个Underscore方法来执行浅层复制:< / p>
groupsArray.push( _.clone(group) );
如果group
有任何嵌套对象,则不会复制它们。 (我在Underscore中没有看到深层复制功能,但如果需要,可以写一个。)