Say I have an array of 5 objects, each with 2 keys (eg, 'title' & 'author').
I want to check the truthiness that 3 SPECIFIC titles exist in the array.
What's the best way to do that?
I have the following... but it doesn't seem very efficient:
const books = [
{ title: 'Book1', author: 'Author1' },
{ title: 'Book2', author: 'Author2' },
{ title: 'Book3', author: 'Author3' },
{ title: 'Book4', author: 'Author4' },
{ title: 'Book5', author: 'Author5' },
];
const certainBooks = books.some((b) => b.title === 'Book2')
&& books.some((b) => b.title === 'Book3')
&& books.some((b) => b.title === 'Book5')
if (certainBooks) {
// Do stuff
}
CodePudding user response:
If the values and number of titles is dynamic, it might be worth creating an index of titles in the array; something with O(1) time complexity for faster lookups
const books = [
{ title: 'Book1', author: 'Author1' },
{ title: 'Book2', author: 'Author2' },
{ title: 'Book3', author: 'Author3' },
{ title: 'Book4', author: 'Author4' },
{ title: 'Book5', author: 'Author5' },
];
const titleIndex = new Set(books.map(({ title }) => title));
const titlesExist = (...titles) =>
titles.every(title => titleIndex.has(title))
console.log("Book2, Book3, Book5:", titlesExist("Book2", "Book3", "Book5"));
console.log("Book1:", titlesExist("Book1"));
console.log("Book5, Book6:", titlesExist("Book5", "Book6"));
CodePudding user response:
A more general approach would be to map the books to their titles, then check that .every
one of the titles you're looking for exists.
const books = [
{ title: 'Book1', author: 'Author1' },
{ title: 'Book2', author: 'Author2' },
{ title: 'Book3', author: 'Author3' },
{ title: 'Book4', author: 'Author4' },
{ title: 'Book5', author: 'Author5' },
];
const titles = books.map(({ title }) => title);
const toFind = ['Book2', 'Book3', 'Book5'];
if (toFind.every(title => titles.includes(title))) {
console.log('do stuff');
}
If the array of books is large, you could benefit by making titles
a Set instead of an array - Set#has
is faster than Array#includes
when there are a lot of elements.
CodePudding user response:
You could loop over them
const books = [
{ title: "Book1", author: "Author1" },
{ title: "Book2", author: "Author2" },
{ title: "Book3", author: "Author3" },
{ title: "Book4", author: "Author4" },
{ title: "Book5", author: "Author5" },
];
const booksNeeded = ["Book2", "Book3", "Book4"];
for (let book of books) {
const lookForIndex = booksNeeded.findIndex(
(title) => title.toLowerCase() === book.title.toLowerCase()
);
if (lookForIndex !== -1) {
booksNeeded.splice(lookForIndex, 1);
}
if (!booksNeeded.length) {
break; // Early break if all the books has been found
}
}
if (!booksNeeded.length) {
console.log("Do Something");
} else {
console.log("Something else");
}
CodePudding user response:
const books = [
{ title: 'Book1', author: 'Author1' },
{ title: 'Book2', author: 'Author2' },
{ title: 'Book3', author: 'Author3' },
{ title: 'Book4', author: 'Author4' },
{ title: 'Book5', author: 'Author5' },
];
let ops = 0;
let search = [ "Book2", "Book3", "Book4" ];
let { length } = search;
for ( let i = 0, len = books.length; length && i < len; i ){
ops ;
if ( search.includes(books[i].title) ){
length--;
}
}
if ( !length ){
console.log("All books found!");
} else {
console.log("Not all books found!")
}
console.log( "Number of operations: ", ops );