Caleb
Caleb

Reputation: 31

Accessing Random Property of Object

I have a huge object that contains the entire ESV Bible. I am trying to get a random book of the Bible whenever I press a button. Here is a small sample of the object.

var esvObject = {

 "Genesis": {

    "1": {}
    "2": {}
    "3": {}

   },
 "Exodus": {

    "1": {}
    "2": {}
    "3": {}

   }

}

Here is the code that I am using to get a random book.

var randNum = Math.floor(Math.random() * 66);

var randBook = esvObject[randNum];

var output = randBook;

I would expect this to work, but the output I always get is "undefined," where as I would like the output to be "Genesis" or "Exodus" etc. Getting the random number works, but if

randNum = 1

then

randBook = esvObject[1]

the output returns as "undefined" and I don't know why.

Upvotes: 0

Views: 88

Answers (5)

mistahenry
mistahenry

Reputation: 8724

Well the reason you get undefined is that your object is of the structure:

let esvObject = {
   bookName: {
      1 : {}
   }
}

Using bracket [] notation on a javascript object finds the matching key for the name and returns it's value. In your top level object (the one with bookNames for keys), you have to use a valid book name like Genesis. To do so, leverage the Object.keys function of javascript to get an array of all the keys in your object.

You can then use [] notation, which has a different semantic on arrays.

let books = Object.keys(esvObject); // ["Genesis", "Exodus", ...]
let randomKey = books[randNum] // this is an array, so index access works
let book = esvObject[randomKey]  // matches on the bookname

And to tie it all together, esvObject["Genesis"][1] would have been valid because the object stored as "Genesis" has a property 1

Upvotes: 1

andydavies
andydavies

Reputation: 3293

You're confusing accessing an array with accessing an object.

An array:

arr = ["genesis", "exodus"]

is accessed like this:

arr[0] // genesis

An object:

obj = { "genesis" : "foo", "exodus" : "bar"}

is accessed like this:

obj["genesis"] // foo

To achieve what you want to do, see Access non-numeric Object properties by index?

Upvotes: 0

idmean
idmean

Reputation: 14875

esvObject (as you show it) does not have any integer keys. So you need to select a random (existing) key instead:

esvObject[Object.keys(esvObjects)[Math.floor(Math.random() * 66)]]

Upvotes: 0

Simmol
Simmol

Reputation: 1

It would not work because it does not know that the first book is named "Genesis". To be able to use numbers from the random function you will need to use array from the keys of the object

var keys = esvObject.keys( obj );
randBookKey = keys[randNum]
randBook = esvObject[randBookKey]

Upvotes: 0

Suxino
Suxino

Reputation: 169

You are generating random number. And then trying to pick property using that number.

But you object has properties Genesis and Exodus not 1 or 20 etc. What you need to do is Object.getOwnPropertyNames(esvObject) that will give you array of the property names. In this case ['Genesis', 'Exodus'] and then you need to pick random element from that array

Upvotes: 0

Related Questions