Question

How can I do something like the following in JS? I would like to imitate .pop() on an object rather than an array.

var deck = { 
    'cardK' :'13',
    'cardQ' :'12',
    'cardAJ':'11'
};

var val = deck.pop();


console.log("Key" + val.key ); 
console.log("Value" + val.val ); 

It seems like it's not possible.

Was it helpful?

Solution

.pop is only available on an array. In JavaScript, objects (which are essentially associative arrays) are not ordered like an array, so there is no .pop method.

You could use an array:

var deck = [
    { key: 'cardK', val: 13 },
    { key: 'cardQ', val: 12 },
    { key: 'cardAJ', val: 11 },
];

var val = deck.pop();
console.log('key: ' + val.key);
console.log('aa: ' + val.val);

OTHER TIPS

As suggested by other answers, the best solution here might be to use an array of objects. However you could also create your own pop function that removes a key from an object, for example:

function pop(obj) {
    var key = Object.keys(obj).pop();
    var result = {key: key, val: obj[key]};
    delete obj[key];
    return result;
}

var val = pop(deck);

You could add a similar pop function to Object.prototype so that you could do deck.pop(), but I would strongly recommend against that type of design.

You are right, it's not possible. See objects as maps or hash tables, rather than "associative arrays". The properties don't have an order and thus a method such as .pop would not make sense (unless of course it would remove a random property, like Python's dictionaries).

If you want to to use .pop and val.key and val.val, you have to create an array of objects instead:

var deck = [
  {key: 'cardK', val: '13'},
  {key: 'cardQ', val: '12'},
  {key: 'cardAJ', val: '11'}
];

As I'm sure you know, .pop is a prototypal Array method, so you can't use it with Javascript objects.

Calling .pop on an array will remove the last element from the array. However, there isn't a "last" key-value pair with objects, as their order is not ever guaranteed. Despite this, if you don't care about order, you could implement a .pop-like function for use with objects, though, again, it wouldn't remove and return the final key-value pair.

Something like this should do the trick:

function pop(obj) {
  for (var key in obj) {
    var val = obj[key];
    delete obj[key];
    return {
        'key'   : key,
        'val'   : val,
    };
  };
};

Combined with your code:

var val = pop(deck);
console.log('key: ' + val.key);
console.log('aa: ' + val.val);

When working with this structure, which can be thought of as an associative array, you need to use different techniques. Things like pop(), slice() and even .length will not work as they do with numeric keyed arrays.

I use string keyed object arrays when searching for the key/value pair needs to happen fast.

Here's a jsPef I just created which shows the benefit of your array structure:

http://jsperf.com/bmcgin-object-array-tests (keep in mind the performance goes way up as the array gets bigger)

Also keep in mind the value can be a number, a string, an array, a function, an object ect...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top