5
\$\begingroup\$

HackerRank currently has '7 days of JavaScript' going, a quick intro into the JavaScript language. Every day a couple of challenges will be made available. One of the challenges of today was this:

Task

Write a JavaScript program to display the status (i.e. display book name, author name and reading status) of books. You are given an object library in the code's template. It contains a list of books with the above mentioned properties. Your task is to display the following:

  • If the book is unread:

You still need to read '<book_name>' by <author_name>.

  • If the book is read:

Already read '<book_name>' by <author_name>.

library was provided, as was the empty function displayInformation() (and no, it is not allowed to pass library as an argument to the function).

The required code is as straight-forward as it gets, but I feel there's a more proper way to do the string formatting.

function displayInformation() {
    for (var i = 0; i < library.length; i++) {
        if (library[i].readingStatus) {
            console.log("Already read '" + library[i].title + "' by", library[i].author + ".");
        } else {
            console.log("You still need to read '" + library[i].title + "' by", library[i].author + ".");
        }
    }
} 

// provided by HackerRank
var library = [ 
    {
        title: 'Bill Gates',
        author: 'The Road Ahead',
        readingStatus: true
    },
    {
        title: 'Steve Jobs',
        author: 'Walter Isaacson',
        readingStatus: true
    },
    {
        title: 'Mockingjay: The Final Book of The Hunger Games',
        author: 'Suzanne Collins',
        readingStatus: false
    }
];

displayInformation();

As you can see, I'm inconsistent within the console.log() functions and there's needless repetition. I'm also hacking my way into the library where I feel a more OO approach would look better. I think separating whatever you want to send to console.log() should be done by comma's whenever possible and concatenation should only be used if there's no other way.

Since I have to print the name of the book between ' ', I picked concatenation for whenever the usual style (comma's) wouldn't work. Now it looks like a mess. Should I've switched to concatenation the moment one part of the string is using it?

Does JavaScript have something like a string.format() or would that make it look worse?

I'm not sure this is the idiomatic way of retrieving all the elements from the library either. Or hey, I may just be over-thinking a simple challenge.

\$\endgroup\$
4
\$\begingroup\$

To avoid repeating console.log(), you can use library.reduce() which'll output a global result, then passed to the console only once.

Regarding your other concern about efficient concatenation, you can use tagged strings.

It results in a more compact code, like this:

var library = [ 
    {
        title: 'Bill Gates',
        author: 'The Road Ahead',
        readingStatus: true
    },
    {
        title: 'Steve Jobs',
        author: 'Walter Isaacson',
        readingStatus: true
    },
    {
        title: 'Mockingjay: The Final Book of The Hunger Games',
        author: 'Suzanne Collins',
        readingStatus: false
    }
];

function displayInformation() {
  console.log(library.reduce( (output, book) => output +=
    `${book.readingStatus ? 'Already read' : 'You still need to read'} ${book.title} by ${book.author}.\n`, ''
  ));
}

displayInformation();

\$\endgroup\$
1
\$\begingroup\$

There's a few ways to skin this particular cat:

  • ES6: Use template strings: something like 'Hello, ' + place + '!' turns into `Hello, ${place}!`
  • Concatenate later:

var statusPrefix = library[i].readingStatus
    ? "Already"
    : "You still need to";
console.log(statusPrefix + ' read ' + library[i].title + "' by", library[i].author + '.');

It's better to define what library[i] is, or you can use forEach:

function printBookStatus(book){
    var statusPrefix = book.readingStatus
        ? "Already"
        : "You still need to";
    console.log(`${statusPrefix} read "${book.title}" by ${book.author}.`);
}

library.forEach(printBookStatus);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.