5

I am trying to write a program that takes an input (library, authorName) and returns the title of books the author wrote.

The library looks like this:

let library = [
  { author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
  { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
  { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];

My code looks like this:

let library = [
  { author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
  { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
  { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];

function searchBooks(library, author) {
  for (author in library) { //enumerate
    if (author in library) {
      let line = Object.values(library[0]) // find line of the wanted author
      let result = (line[0] + "," + line[1]) // store author name and title name
      return result
    } else {
      return "NOT FOUND"
    }
  }
}

console.log(searchBooks(library, 'Bill Gates'))

The output looks like this: Bill Gates,The Road Ahead

The problem: No matter what author I will input into searchBook it returns Bill Gates, the first line of the library. Thus, it does not enumerate I guess. But why not?

I first thought maybe I have to avoid hard coding [0] and [1] and instead use i and i++. But this does not seem to work either as it then outputs TypeError: Cannot convert undefined or null to object

2
  • 2
    for (author in library) iterates over the keys of the array. Commented Mar 13, 2020 at 5:07
  • let line = Object.values(library[0]) also, this would always gets the first item in the array, regardless of how many loops you have. Commented Mar 13, 2020 at 5:09

4 Answers 4

3

A few things:

  1. for (author in library) is looking up each key of your library array, instead use of which evaluates each value. Since it's an object, I've named that value book
  2. your result may have many values, so best to make it an array or collection of some sort, which you can stack responses in
  3. if (author in library) checks to see if your author is a key in the original library array, again not desired. You really want to see if author is a value of the object. More specifically, you want your author to be a value of the object's author key. So book.author == author
  4. your result is an array, so join the values with a newline; if there are no items in your result array it will be an empty string, which is a falsey value. In that case that's when you can return your NOT FOUND message. Otherwise you want to return all the books

let library = [
  { author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
  { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
  { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];

function searchBooks(library, author) {
  let result = []

  for (let book of library) {
    if (book.author == author) {
      let line = Object.values(book)       // find line of the wanted author
      result.push(line[0] + "," + line[1]) // store author name and title name
    }
  }

  return result.join('\n') || 'NOT FOUND'
}

console.log(1, searchBooks(library, 'Carolann Camilo'))
console.log(2, searchBooks(library, 'Bill Gates'))
console.log(3, searchBooks(library, 'Oh boy'))

Note:

  • For ways to avoid Object.values see this answer
  • For ways to iterate over the library for only desired books (using filter), seek this answer
  • For another way to iterate over library (using forEach), seek this answer
Sign up to request clarification or add additional context in comments.

Comments

1

You may want to use Array.filter (see MDN):

const library = [
  { author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
  { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
  { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];

console.log(findAuthor(library, `Bill Gates`));

function findAuthor(library, author) {
  return library.filter(book => book.author === author);
}

6 Comments

I think OP is a beginner, this approach is too advanced and not that helpful for understanding the problem.
Let OP be the judge of that, I'd say
I also think it's too advanced, which is why I kept the answer close to what he wrote; however, I think this is a good answer to include. It's good to cover the depth of information.
I totally agree with that, but it's also important to explain why his butter knife doesn't work. It's better to tell them what they did wrong than just let them copy-paste the answer without understanding it.
So the problem is not that this solution is "too advanced" (it really isn't btw, Array.filter is part of basics), but that this answer didn't explained what was wrong. On this I can agree.
|
0

You can use forEach to loop over the elements and add them to a given result for multiple entries of the same author

let library = [
  {author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
  { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
  { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];
function search(library, author) {
  let result = ""
  library.forEach(l => {
    if (l.author === author) {
      result += l.author+", "+l.title+"\n"
    }
  })
  return result
}

console.log(search(library, "Carolann Camilo"))

Comments

0

Here's a working version of your approach:

let library = [
    { author: 'Bill Gates', title: 'The Road Ahead', libraryID: 1254 },
    { author: 'Carolann Camilo', title: 'Eyewitness', libraryID: 32456 },
    { author: 'Carolann Camilo', title: 'Cocky Marine', libraryID: 32457 }
];

function searchBooks(library, author) {
    for (const book of library) { //enumerate
        if (book.author === author) {
            let result = (book.author + "," + book.title) // store author name and title name
            return result
        }
    }
    return 'NOT FOUND'
}

console.log(searchBooks(library, 'Bill Gates'))

  • First, iterate the books in the library, not the author.

  • Then find out if the author of the book is equal to the author you want to find.

  • Then output the author and title of that book separated by a comma.

Also be aware this only returns the first match, not all matches.

Comments

Your Answer

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