最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can I use filter to extract values from an array of objects? - Stack Overflow

programmeradmin5浏览0评论

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 acplished using map. But I am trying to acplish it using filter.

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 acplished using map. But I am trying to acplish it using filter.

Share Improve this question edited Nov 1, 2020 at 18:56 custommander 19.1k6 gold badges69 silver badges93 bronze badges asked Nov 1, 2020 at 18:29 captaincustardcaptaincustard 3611 gold badge4 silver badges12 bronze badges 4
  • What you need is map, not filter: const titles = books.map(book => book.title);. filter is for FILTERing not for mapping – ibrahim mahrir Commented Nov 1, 2020 at 18:33
  • developer.mozilla/en-US/docs/Web/JavaScript/Reference/… You can read about filter method here, it clearly does not do what you are trying to achive – Akash Karnatak 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? – captaincustard 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. – Nina Scholz Commented Nov 1, 2020 at 18:38
Add a ment  | 

2 Answers 2

Reset to default 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);

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"

发布评论

评论列表(0)

  1. 暂无评论