1

I'm trying to create a javascript object that would easily let me check how many chapters there are in a certain book and how many verses there are in a certain chapter.

My plan is to have a structure like this for the object:

const amounts = {
    book: {
        bookNumber: 1,
        bookChapters: 50,
        chapter:
        {
            chapterNumber: 1,
            versesInChapter: 31
        },

        chapter:
        {
            chapterNumber: 2,
            versesInChapter: 25
        }
    },

    book: {
        bookNumber: 2,
        bookChapters: 40,
        chapter:
        {
            chapterNumber: 1,
            versesInChapter: 26
        },

        chapter:
        {
            chapterNumber: 2,
            versesInChapter: 22
        }
    }

}

How could I access the nested values of such a structure based on variable values? For example I might have a var bookNum = 2 and var chapterNum = 2 and my goal would be to get the number of verses in chapter 2 inside book 2. How would I write such a query?

EDIT: Based on the comments my object structure is also bad, so I'm asking to also point out the correct structure that would allow me to access the amount of verses efficiently.

5
  • Isn't chapter meant to be an array? And, for that matter, shouldn't each book have a unique name? Currently the last property will override the first, leaving you with a single book containing a single chapter. Commented Apr 29, 2019 at 5:21
  • Not sure, would it help? Can't it just be a nested object? I'm pretty new to this stuff.. Commented Apr 29, 2019 at 5:23
  • You have two same keys book which will overwrite the first one. And same will happen with chapter Commented Apr 29, 2019 at 5:23
  • 1
    Two identical keys - the later value will override the first value. Commented Apr 29, 2019 at 5:24
  • I will edit my post to point out that I might also need a better structure for the object. Commented Apr 29, 2019 at 5:24

3 Answers 3

2

You can rewrite your var amounts as below formate it will help in manipulation

const books = [
 {
        bookNumber: 1,
        bookChapters: 50,
        chapter:[
        {
            chapterNumber: 1,
            versesInChapter: 31
        },
        {
            chapterNumber: 2,
            versesInChapter: 25
        }
    ],
}

    {
        bookNumber: 2,
        bookChapters: 40,
        chapter:[
        {
            chapterNumber: 1,
            versesInChapter: 26
        },

        {
            chapterNumber: 2,
            versesInChapter: 22
        }
    ]
    }

]

const books = [{
    bookNumber: 1,
    bookChapters: 50,
    chapter: [{
        chapterNumber: 1,
        versesInChapter: 31
      },
      {
        chapterNumber: 2,
        versesInChapter: 25
      }
    ],
  },

  {
    bookNumber: 2,
    bookChapters: 40,
    chapter: [{
        chapterNumber: 1,
        versesInChapter: 26
      },

      {
        chapterNumber: 2,
        versesInChapter: 22
      }
    ]
  }

]

var serach = books.filter(function(book) {
  //console.log("books",book);
  return book.bookNumber == 1;
})[0];
console.log("Searched book!", serach)

//And for desired result you can use forEach and filter 
var num = 2,
  chap = 1,
  found_chapter;

books.forEach(function(book) {
  if (book.bookNumber == num) { //found the book
    console.log("found book", book);
    found_chapter = book.chapter.filter(function(chapter) {
      return chapter.chapterNumber == chap; //found chapter WRT found book
    })[0]

  }
});
console.log("found chapter-", found_chapter, "--found verse", found_chapter.versesInChapter)

And as an above snippet, you can filter out your serach data and can easily loop it again to find the desired result

Hope this helps you !

Sign up to request clarification or add additional context in comments.

1 Comment

How about the chapter number? Also, this does not appear to return the desired result, OP is looking for returning versesInChapter from the object.
0

You could structure this data in two ways; as an array or as an object.

Method 1 (object)

As the books are indexed by bookNumber, it would make sense for the bookNumber to be a key in an object.

This can be reduced down to:

{
  bookNumber: {
    chapterNumber: versesInChapter, 
     ...
  }, 
  ...
}

I've added some comments in my code to help clarify.

const books = {
  1: {
    1: 31,
    2: 25
  },
  2 /*bookNumber*/: {
    1 /*chapterNumber*/: 26 /*versesInChapter*/ ,
    2 /*chapterNumber*/: 22 /*versesInChapter*/
  }
};

// es6 style function. Same as `function getVerses(bookNum, chapterNum){...}`
getVerses = (bookNum, chapterNum) => {
  if (books[bookNum] && books[bookNum][chapterNum]) {
    return books[bookNum][chapterNum];
  } else {
    // Notify that the index is not set
    console.warn('Warning: Book or chapter number is not defined!');
    // Return 0 as deafult
    return 0;
  }
}

let bookNum = 2;
let chapterNum = 2;
let numOfVerses = getVerses(bookNum, chapterNum);
console.log(`Book ${bookNum} chapter ${chapterNum} has ${numOfVerses} verses.`);

Method 2 (array)

If these books are to be sequential, an array would also work.

[
  [versesInChapter/*1*/,versesInChapter/*2*/, ...],
  ...
]

For example:

const books = [
   [31,25],
   [26,22]
];

// es6 style function. Same as `function getVerses(bookNum, chapterNum){...}`
getVerses = (bookNum, chapterNum) => {
  bookNum--;
  chapterNum--;
  if (books[bookNum] && books[bookNum][chapterNum]) {
    return books[bookNum][chapterNum];
  } else {
    // Notify that the index is not set
    console.warn('Warning: Book or chapter number is not defined!');
    // Return 0 as deafult
    return 0;
  }
}

let bookNum = 2;
let chapterNum = 2;
let numOfVerses = getVerses(bookNum, chapterNum);
console.log(`Book ${bookNum} chapter ${chapterNum} has ${numOfVerses} verses.`);

Hope this helps,

3 Comments

I appreciate your efforts to keep books object small. The problem with this is code becomes little bit difficult to read and in future if things gets added to in books object it will be very difficult incorporate those changes without changing/breaking existing functionality but it will definitely solve the current problem. :)
I liked this solution a lot, ended up implementing the array method and it works great!
Glad to hear it! GLHF
0

You could structure books and chapters as arrays. Then you could access each piece of data within them like:

var books = [
  {
    name: "Book1",
    chapters: [
      { countOfVerses: 31 },
      { countOfVerses: 20 }
    ]
  },
  {
    name: "Book2",
    chapters: [
      { countOfVerses: 12 },
      { countOfVerses: 20 },
      { countOfVerses: 16 },
      { countOfVerses: 22 }
    ]
  }    
];

for (let book of books){
  let name = book.name; // Now we know which book it is...
  let chapterCount = book.chapters.length; // ...and how many chapters it has
  console.log(`${name} has ${chapterCount} chapters:`)

  for (let i = 0; i < chapterCount; i++){
    let chapter = book.chapters[i]; // Look in each chapter in the book...
    let verses = chapter.countOfVerses; //...and get the countOfVerses property
    console.log(`  Chapter ${i+1} has ${verses} verses`);
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.