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
, notfilter
: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
2 Answers
Reset to default 6If 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"