Access non-numeric Object properties by index?

JavascriptArrays

Javascript Problem Overview


If I have an array like this:

var arr = ['one','two','three'];

I can access different parts by doing this:

console.log(arr[1]);

How can I access object properties by their order rather than by key?

Example:

var obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
},
jbo = {
    'evenmore'  : 'crazy',
    'something' : 'awesome'
};

How would I get the first property for each object–"something" from obj and "evenmore" from jbo–without explicitly using the property name?

Now, a few of you seem to think I'm after something like:

console.log(obj['something']);

This is not the case, I'm specifically looking to target the index, just like the first example - if it's possible.

Javascript Solutions


Solution 1 - Javascript

>"I'm specifically looking to target the index, just like the first example - if it's possible."

No, it isn't possible.

The closest you can get is to get an Array of the object's keys, and use that:

var keys = Object.keys( obj );

...but there's no guarantee that the keys will be returned in the order you defined. So it could end up looking like:

keys[ 0 ];  // 'evenmore'
keys[ 1 ];  // 'something'

Solution 2 - Javascript

The only way I can think of doing this is by creating a method that gives you the property using Object.keys();.

var obj = {
    dog: "woof",
    cat: "meow",
    key: function(n) {
        return this[Object.keys(this)[n]];
    }
};
obj.key(1); // "meow"

Demo: http://jsfiddle.net/UmkVn/

It would be possible to extend this to all objects using Object.prototype; but that isn't usually recommended.

Instead, use a function helper:

var object = {
  key: function(n) {
    return this[ Object.keys(this)[n] ];
  }
};

function key(obj, idx) {
  return object.key.call(obj, idx);
}

key({ a: 6 }, 0); // 6

Solution 3 - Javascript

You can use the Object.values() method if you dont want to use the Object.keys().

As opposed to the Object.keys() method that returns an array of a given object's own enumerable properties, so for instance:

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.keys(object1));

Would print out the following array:

[ 'a', 'b', 'c' ]

The Object.values() method returns an array of a given object's own enumerable property values.

So if you have the same object but use values instead,

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.values(object1));

You would get the following array:

[ 'somestring', 42, false ]

So if you wanted to access the object1.b, but using an index instead you could use:

Object.values(object1)[1] === 42

You can read more about this method here.

Solution 4 - Javascript

var obj = {
    'key1':'value',
    '2':'value',
    'key 1':'value'
}

console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])

// will not work
console.log(obj.2)

Edit:

>"I'm specifically looking to target the index, just like the first example - if it's possible."

Actually the 'index' is the key. If you want to store the position of a key you need to create a custom object to handle this.

Solution 5 - Javascript

by jquery you can do this:

var arr = $.map(obj,function(value, key) {
    return value;
});
alert(obj[0]);

Solution 6 - Javascript

Get the array of keys, reverse it, then run your loop

  var keys = Object.keys( obj ).reverse();
  for(var i = 0; i < keys.length; i++){
    var key = keys[i];
    var value = obj[key];
    //do stuff backwards
  }

Solution 7 - Javascript

Yes, it is possible. We can define getters for each index, and return the property value, in the constructor method of the class. See this code.

class className {
  constructor() {
    this.name = "Bikram";
    this.age = 8;
    this.x = 89;
    this.y = true;


//Use a for loop and define the getters (with the object property's index as its "name") for each property using Object.defineProperty()

    for (let i = 0; i < Object.keys(this).length; i++) {

      Object.defineProperty(this, i, {
        get: function() {
          return Object.values(this)[i]}
      });
    }

  }
}


var b = new className();
console.log(b[0]); // same as b.name ("Bikram")
console.log(b[1]); // = b.age (8)
console.log(b[2]); // = b.x (89)
console.log(b[3]); // = b.y (true)

Edit: If you want to change the properties by their indices, which, of course, you do. Then, just define a corresponding setter for each property in the Object.defineProperty() method. It will look like:

// Insert this in place of the old one 

     Object.defineProperty(this, i, {
       get: function() {
          return Object.values(this)[i];
        },
        set: function(newValue) {
          this[Object.keys(this)[i]] = newValue;
        }
     })

     console.log(b[0]); // "Bikram"

     b[0] = "Bikram Kumar";

     console.log(b[0]); // "Bikram Kumar"

And now you have an "array-like-object" whose properties can be accessed or modified either by property key or its index :D

A side note: Notice that Object.keys() and Object.values() only return the enumerable properties. If you just declare a property and not assign it to any value, the Object.[key/value]s() methods will leave that in the returned array, because by default they are not enumerable. This might become confusing for the indices so defined (except the case the undeclared property is the last one).

To get around this, there is a simple way, if you want some property to have a index, but don't wanna assign it now. Just set it to undefined, and it will now be enumerable, and the indices won't be affected.

Solution 8 - Javascript

you can create an array that filled with your object fields and use an index on the array and access object properties via that

propertiesName:['pr1','pr2','pr3']

this.myObject[this.propertiesName[0]]

Solution 9 - Javascript

I went ahead and made a function for you:

 Object.prototype.getValueByIndex = function (index) {
     /*
         Object.getOwnPropertyNames() takes in a parameter of the object, 
         and returns an array of all the properties.
         In this case it would return: ["something","evenmore"].
         So, this[Object.getOwnPropertyNames(this)[index]]; is really just the same thing as:
         this[propertyName]
    */
    return this[Object.getOwnPropertyNames(this)[index]];
};

let obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
};

console.log(obj.getValueByIndex(0)); // Expected output: "awesome"

Solution 10 - Javascript

Sure it is possible, but it is not as immediate as accessing to an array by its indexes, but still possible and even relatively simple actually: in fact you don't have to struggle too much. This code sample will show how:

var obj = {
    'alfa'  : 'value of obj the key alfa',
    'beta'  : 'value of obj the key beta',
    'gamma'  : 'value of obj the key gamma'
};

var jbo = {
    'alfa'  : 'value of jbo the key alfa',
    'beta'  : 'value of jbo the key beta',
    'gamma'  : 'value of jbo the key gamma'
};

alert  ( obj[Object.keys(obj)[1]] );
alert ( jbo[Object.keys(jbo)[1]] );

/* you can even put it into a for loop as follows */

for (i=0;i<3;i++)
{
    document.writeln ( "<br>This could be even a piece of HTML: " + obj[Object.keys(obj)[i]] );
    document.writeln ( "<br>This could be even a piece of HTML: " + jbo[Object.keys(jbo)[i]] );
}

Explication:

As you know the Object.keys() statement returns an array of all enumerable properties (which means all keys) of the object you type into its round parenthesis. So the only thing you need is to indicate the index after that array, which will returns the key literal found at that index. The key itself is "digested" as usual by the object which returns the value at that key.

Solution 11 - Javascript

If you are not sure Object.keys() is going to return you the keys in the right order, you can try this logic instead

var keys = []
var obj = {
    'key1' : 'value1',
    'key2' : 'value2',
    'key3' : 'value3',
}
for (var key in obj){
    keys.push(key)
}
console.log(obj[keys[1]])
console.log(obj[keys[2]])
console.log(obj[keys[3]])

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondarylView Question on Stackoverflow
Solution 1 - Javascriptuser113716View Answer on Stackoverflow
Solution 2 - JavascriptDavid GView Answer on Stackoverflow
Solution 3 - JavascriptArthur SennaView Answer on Stackoverflow
Solution 4 - JavascriptcuzzeaView Answer on Stackoverflow
Solution 5 - JavascriptMeysam KhoshbakhtView Answer on Stackoverflow
Solution 6 - JavascriptKareemView Answer on Stackoverflow
Solution 7 - JavascriptBikram KumarView Answer on Stackoverflow
Solution 8 - JavascriptarfaView Answer on Stackoverflow
Solution 9 - Javascriptuser14029620View Answer on Stackoverflow
Solution 10 - Javascriptwilly wonkaView Answer on Stackoverflow
Solution 11 - JavascriptThiago LoddiView Answer on Stackoverflow