1

这里是 Javascript 新手——

我有以下数组:

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。

我究竟做错了什么?

谢谢。

4

1 回答 1

2

首先,它有助于理解为什么$.inArray()不起作用。让我们尝试一个更简单的案例。将其粘贴到浏览器中加载了 jQuery 的页面上的 JavaScript 控制台(例如我们所在的这个页面)并运行它:

var object = { a: 1 };
var array = [ { a: 1 } ];
console.log( '$.inArray: ', $.inArray( object, array ) );

(注意术语:你的group变量是一个对象,而不是一个数组。)

现在它看起来像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属性。例如,如果groupis {a:1},它将匹配groupsArray数组中的对象是{a:1,b:2}

如果您需要完全匹配,您可以结合下划线_.find()_.isEqual()方法:

var index = _.find( groupsArray, function( element ) {
    return  _.isEqual( element, group );
});

现在要注意的最后一件事。您将group对象推送到groupsArray数组上的代码 - 您知道推送实际group对象本身。它不会在数组中复制它,它是对同一个对象的引用。(具有讽刺意味的是,这意味着您group在数组中查找的原始代码实际上可以在您自己将同一个group对象推送到数组的情况下工作。)

如果您想确保其中的groupsArray每个元素都是它们自己的独立对象,而不是对代码中浮动的另一个对象的引用,您可以使用另一个 Underscore 方法进行浅拷贝:

groupsArray.push( _.clone(group) );

但是,如果group有任何嵌套对象,则不会复制它们。(我在 Underscore 中没有看到深拷贝功能,但如果需要,您可以编写一个。)

于 2013-04-05T17:35:57.120 回答