2

I have an array of objects:

const books = [
  {
    title: 'Book',
    author: 'Name'
  },
  {
    title: 'Book2',
    author: 'Name2'
  }
];

I'd like to extract the titles into an array using the filter method. So far I tried this but the array returns with the 2 original objects:

const getTheTitles = function(array) {
   const filteredArray = array.filter(function(book) {
      return book.title;
   })
   return filteredArray;
}

I also tried this but it results in an empty array (not sure why):

const getTheTitles = function(array) {
   const filteredArray = array.filter(function(book) {
      book.title;
   })
   return filteredArray;
}

I understand that this could be accomplished using map. But I am trying to accomplish it using filter.

4
  • What you need is map, not filter: const titles = books.map(book => book.title);. filter is for FILTERing not for mapping Commented Nov 1, 2020 at 18:33
  • developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… You can read about filter method here, it clearly does not do what you are trying to achive Commented Nov 1, 2020 at 18:36
  • Thank you. As mentioned, I am aware of being able to use map. Is there a way to do it using filter? Or is it impossible as I won't be able to specify a criteria for filtering? Commented Nov 1, 2020 at 18:37
  • with filter you can only decide which item of the array should be in the filterd array, but you can not change the item. Commented Nov 1, 2020 at 18:38

2 Answers 2

6

If you want to get the titles of certain filtered books, then either do it by chaining map to filter, like so:

let filteredBookTitles = books
  .filter(book => book.author === "Some Name")           // first filter (us any criteria here to select only the books you want)
  .map(book => book.title);                              // then get the titles of those filtered books

Demo:

const books = [{ title: "Animal Farm", author: "George Orwell" }, { title: "Oliver Twist", author: "Charles Dickens" }, { title: "1984", author: "George Orwell" }];

let georgeOrwellBooks = books.filter(book => book.author === "George Orwell")
  .map(book => book.title);

console.log(georgeOrwellBooks);

Or by using a reduce to do both while looping the array only once, like so:

let filteredBookTitles = books.reduce((acc, book) => {   // for each book in the books array
  if(book.author === "Some Name") {                      // if the book matches the criteria
    acc.push(book.title);                                // add its title to the results array
  }

  return acc;
}, []);

Demo:

const books = [{ title: "Animal Farm", author: "George Orwell" }, { title: "Oliver Twist", author: "Charles Dickens" }, { title: "1984", author: "George Orwell" }];

let georgeOrwellBooks = books.reduce((acc, book) => {
  if(book.author === "George Orwell") {
    acc.push(book.title);
  }

  return acc;
}, []);

console.log(georgeOrwellBooks);

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

Comments

2

You can only use Array#filter to remove items but not to transform them. The filter function is applied to each item. If the function returns true (or anything that is truthy) the item is kept otherwise it is removed.

Example: keeping only odd numbers:

[1,2,3,4,5].filter(n => n % 2 !== 0);
//=> [1,3,5]

Example: removing false from an array of booleans:

[true,false,true,false].filter(b => b);
//=> [true,true]

What you're trying to do is to transform all items. e.g. from [{n:1},{n:2},{n:3}] to [1,2,3]. In this case you need Array#map which applies a function to all items and creates a new array with the results:

[{n:1},{n:2},{n:3}].map(o => o.n);
//=> [1,2,3]

Why does this function return all books?

const getTheTitles = function(array) {
  const filteredArray = array.filter(function(book) {
    return book.title;
  })
  return filteredArray;
}

The problem is that your filter function evaluates book.title to decide whether to keep the book object. However all your books have a title and therefore this function is the same as saying "Does this book have a title?"

Why does this function return no books at all?

const getTheTitles = function(array) {
  const filteredArray = array.filter(function(book) {
    book.title;
  })
  return filteredArray;
}

The problem is that your filter function doesn't actually return anything explicitly. When a function has no return statement then it returns undefined by default which is a "falsy" value. This function is the same as saying "Ignore all books"

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.