17

我正在尝试从现有对象中获取一些数据并将其分组为一个新对象。我遇到的问题是检查对象键是否存在,以便我可以创建一个新的,或者将数据附加到现有的。

我发现了一些类似的问题,但没有一个答案有效,所以我有点卡住了。它总是最终发现它不存在并创建重复的键。

我有以下代码,xxx我需要在哪里检查密钥是否存在:

var groups = [];    

for (var i=0; i<something.length; i++) {

    var group_key = 'group_'+something[i].group_id;

    if (xxx) {

        // New group

        var group_details = {};

        group_details[group_key] = {
                group_name: something[i].group_name,
                items:  [
                    { 'name': something[i].name }
                ]
        };
        groups.push(group_details);

    } else {

        // Existing group

        groups[group_key].items.push({
            'name': something[i].name
        });

    }

}

something我传入的,很简单,基本上是这样的形式:

[
    {
        group_id: 3,
        group_name: 'Group 3',
        name: 'Cat'
    },
    {
        group_id: 3,
        group_name: 'Group 3',
        name: 'Horse'
    },
    {
        group_id: 5,
        group_name: 'Group 5',
        name: 'Orange'
    }
]
4

7 回答 7

34

实现这一点的最佳方法是依赖于in操作符返回一个布尔值,该值指示对象中是否存在键。

var o = {k: 0};

console.log('k' in o); //true

但这不是您唯一的问题,您没有任何查找对象可以让您检查密钥是否已经存在。不要使用数组,而是使用普通对象。

var groups = {};

然后代替groups.push(...), 做groups[group_key] = group_details;

然后你可以通过做检查组是否存在if (group_key in groups) {}

于 2013-09-20T18:08:14.813 回答
4

我经常遇到这种模式,我最终要做的是:

if (object[key]) {
    //exists
} else {
    // Does not exist
}

所以我认为在你的情况下它将是:

if (groups[group_key]) {
    // Exists
} else {
    // Does not exist 
}
于 2013-09-20T17:57:59.083 回答
1

let data = {key: 'John'};
console.log( data.hasOwnProperty('key') );

于 2016-12-13T11:36:42.863 回答
1

您应该使用in运算符

key in object     //true
!(key in object)  //false

并且undefined不能使用

obj["key"] !== undefined //false, but the key in the object

有关更多信息,请查看检查 JavaScript 对象中是否存在键?

于 2019-10-20T15:28:21.087 回答
0

您可以使用 hasOwnProperty() 函数。

var groups = [];    

for (var i=0; i<something.length; i++) {

    var group_key = 'group_'+something[i].group_id;

    if (!groups.hasOwnProperty(group_key)) {

        // New group

        var group_details = {};

        group_details[group_key] = {//maybe change to group_details =
                group_name: something[i].group_name,
                items:  [
                    { 'name': something[i].name }
                ]
        };

        //groups.push(group_details);
        //change it to
        groups[group_key] = group_details;

    } else {

        // Existing group

        groups[group_key].items.push({
            'name': something[i].name
        });

    }

}
于 2013-09-20T18:29:01.663 回答
0

您可以从对象中检索键并遍历列表并查看键是否存在:

var keys=Object.keys(object)
for(var i=0;i<keys.length;i++){
     if(keys[i]=="your key"){//check your key here}
}
于 2013-09-20T18:29:28.813 回答
0

示例数组

[0] => siteoverlay
[1] => overlaycenter
[2] => someelementid

解决方案 A

如果你愿意,可以扩展原型,(在这里使用 while 循环比 for in 快得多):

if (!('getKey' in Object.prototype)) {
        Object.prototype.getKey = function(obj) {
        var i=this.length; 
            while(i--)
            {  if(this[i]===obj)
                  {return i;} 
                   return;
            }
       };
}

那么你可以使用:

alert(exampleArray.getKey("overlaycenter"));  

返回:1

解决方案 B

还带有原型扩展:

if(!('array_flip' in Array.prototype)){
      Array.prototype.array_flip=function(array) {
        tmp_ar={}; var i = this.length;
        while(i--)
        {   if ( this.hasOwnProperty( i ) )
               { tmp_ar[this[i]]=i; }
        } return tmp_ar;    
      };
  }

然后你可以使用:

alert(exampleArray.array_flip(exampleArray['someelementid']);

回报:2

解决方案 C

发现没有添加原型它也可以使用

最终更好地兼容脚本,因为每个人都说不要扩展原型......所以......是的,如果你想用一个简单的 1 班轮使用它,那么你可以使用:

    function array_flip( array )
    {  tmp_ar={};  var i = array.length;
        while(i--)
        {  if ( array.hasOwnProperty( i ) )
              { tmp_ar[array[i]]=i; }
        } return tmp_ar;    
    }

alert(array_flip(exampleArray)['siteoverlay']);

返回 0

于 2014-04-05T15:10:53.760 回答