17

I'm trying to take some data from an existing object and group it into a new one. The problem I am having is checking if the object key exists so I can either create a new one, or append data to an existing one.

I've found a few similar questions but none of the answers worked so I'm a bit stuck. It always ends up finding it doesn't exist and creating duplicate keys.

I have the following code, where xxx is where I need to check if the key exists:

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
        });

    }

}

The something I am passing in, is pretty simple, basically in the form of:

[
    {
        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'
    }
]
Vladimir Panteleev
  • 24,651
  • 6
  • 70
  • 114
KenTenMen
  • 240
  • 1
  • 2
  • 10

7 Answers7

34

The best way to achieve this would be to rely on the fact that the in operator returns a boolean value that indicates if the key is present in the object.

var o = {k: 0};

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

But this isin't your only issue, you do not have any lookup object that allows you to check if the key is already present or not. Instead of using an array, use a plain object.

var groups = {};

Then instead of groups.push(...), do groups[group_key] = group_details;

Then you can check if the group exist by doing if (group_key in groups) {}

plalx
  • 42,889
  • 6
  • 74
  • 90
  • Perfick. I can't even remember why I made it an array in the first place but it's been a long day and this has fixed it! – KenTenMen Sep 20 '13 at 18:31
4

I have run into this pattern a lot, and what I end up doing is:

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

so I think in your case it will be:

if (groups[group_key]) {
    // Exists
} else {
    // Does not exist 
}
iConnor
  • 19,997
  • 14
  • 62
  • 97
Tore
  • 1,236
  • 2
  • 11
  • 21
  • 7
    Warning, this exact implementation only works if `object[key]` can never contain a falsey value such as `0` or `false` or `""`. You can compare `object[key] !== undefined` instead and it will work even when there are falsey values. – jfriend00 Sep 20 '13 at 18:01
  • 1
    @jfriend00 very true. In fact I would go so far as to say this answer is incorrect for this very reason. – Matt Sep 20 '13 at 18:10
  • 1
    @jfriend00 What about `({k: void(0)}).k !== undefined; //false`, the most reliable way is with `in`. – plalx Sep 20 '13 at 18:11
1

let data = {key: 'John'};
console.log( data.hasOwnProperty('key') );
  • 4
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – DimaSan Dec 13 '16 at 12:04
1

You should use the in operator

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

And undefined can not be used

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

For more information, please look at Checking if a key exists in a JavaScript object?

Kaibo
  • 111
  • 1
  • 4
0

You can use hasOwnProperty() function.

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
        });

    }

}
Faton
  • 853
  • 1
  • 9
  • 19
0

you could retrieve keys from object and iterate through the list and see if the key is exist or not:

var keys=Object.keys(object)
for(var i=0;i<keys.length;i++){
     if(keys[i]=="your key"){//check your key here}
}
Nishad K Ahamed
  • 1,374
  • 15
  • 25
0

ExampleArray

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

Solution A

extend prototype if you want,(function here with while loop which is much faster than 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;
            }
       };
}

then you can use:

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

returns: 1

Solution B

also with prototype extension:

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;    
      };
  }

and then you can use:

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

returns: 2

Solution C

found out without prototype addition it is also functional

and eventually better for compatible scripting as everyone says not to extend the prototype...and so,...yes, if you want to use it with an easy 1 liner then you can use:

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

And

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

returns 0

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
scorp1984
  • 1
  • 2