Скажем, у меня есть массив из 5 объектов, каждый из которых имеет 2 ключа (например, «название» и «автор»).
Я хочу проверить достоверность того, что в массиве существуют 3 КОНКРЕТНЫХ названия.
Как лучше всего это сделать?
У меня есть следующее... но это не кажется очень эффективным:
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
}
Эта функция может получить 5 тысяч обращений в месяц, так что это будет довольно высокий трафик. Тем не менее, 3 названия являются специфическими - я всегда буду искать одни и те же 3 в возможном массиве из 1-5 книг.
Более общий подход состоит в том, чтобы сопоставить книги с их названиями, а затем проверить, существует ли .every
одно из названий, которые вы ищете.
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.info('do stuff');
}
Если массив книг большой, вы можете извлечь выгоду, создав titles
набор вместо массива — Set#has
быстрее, чем Array#includes
, когда элементов много.
Если значения и количество заголовков являются динамическими, возможно, стоит создать индекс заголовков в массиве; что-то с временной сложностью О(1) для более быстрого поиска
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.info("Book2, Book3, Book5:", titlesExist("Book2", "Book3", "Book5"));
console.info("Book1:", titlesExist("Book1"));
console.info("Book5, Book6:", titlesExist("Book5", "Book6"));
Хороший призыв! В этом случае он будет динамическим только для каждого запроса. Таким образом, клиент может отправить от 1 до 5 книг, и я проверяю наличие 3 конкретных книг по этому запросу, прежде чем приступить к работе.
Мне очень нравится эта идея кстати! Я попробую это, а затем отмечу как решенное!
Вы можете зациклиться на них
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.info("Do Something");
} else {
console.info("Something else");
}
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.info("All books found!");
} else {
console.info("Not all books found!")
}
console.info( "Number of operations: ", ops );
Это то, что вам нужно делать часто? Являются ли три конкретных названия динамическими или фиксированными? Всегда ли это три?