4

I'm working with JSON and would like to iterate over an array and just return the value I'm looking for. For example, if I have an array of objects and each of those objects has information for a particular book, how can I iterate over each object in that array and only return the one that matches?

I've tried using map, like so (but doesn't work the way I need it to):

// books is from my imported JSON object

const favoriteBook = books.map((book) => {
  if (book.title == this.props.params.id) {
    return book;
  }
});

console.log(favoriteBook)

However, when I console.log(favoriteBook), I'm seeing an array with one object returned that matches, plus 'undefined' for all the ones that don't match. How can I have it stop as soon as it finds the match and just return that one? Wondering how to do this with 'filter' if possible (?) or a similar way.

Thanks.

dace
  • 5,819
  • 13
  • 44
  • 74

4 Answers4

10

I suppose this depends if you want to match multiple books or just a single one.

Matching Multiple Books

You can accomplish this via the filter() function, which would handle multiple books :

const favoriteBooks = books.filter((b) => { return b.title == this.props.params.id;});

Matching a Single Book

Otherwise, you likely want the find() function to return a single one :

const favoriteBook = books.find((b) => { return b.title == this.props.params.id;});

Note: Be extremely mindful of how you use the this keyword as it can dramatically change within the context of one of your function calls. You might consider storing it prior to calling the functions or referencing it a different way to avoid unexpected results.

Rion Williams
  • 74,820
  • 37
  • 200
  • 327
  • Correct, but again note the caveat in my comment to the OP about the value of `this` in that callback. – Pointy May 11 '16 at 20:52
2

You want .find (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

const favoriteBook = books.find((book) => {
    return book.title == this.props.params.id
}.bind(this)); //.bind for context of 'this'
tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • `.find` will return the first match only. It is useful if you are trying to find a specific object, however, if you need to return multiple objects that matches a criteria, this won't work. https://jsfiddle.net/crabbly/1gm8x6sm/ – crabbly May 11 '16 at 19:53
  • @crabbly -- Yep - I assumed `.find` was what OP was looking for since the variable was `favoriteBook`. – tymeJV May 11 '16 at 19:58
  • Yea, It wasn't very clear. Trying to search by id, however, the question title says "matched values". @tymeJV – crabbly May 11 '16 at 20:08
  • @crabbly - Damn these mixed signals, description: "only return the one that matches" haha.\ – tymeJV May 11 '16 at 20:12
2

Try using a .filter() to get only the items that you want, and after this use .map() to get your specific field.

1

Try this:

const favoriteBook = books.find((book) => (book.title === this.props.params.id));
dlopez
  • 969
  • 5
  • 17