Фильтрация во вложенных объектах

Проблема с небольшим тренировочным заданием. Есть экземпляр класса библиотека, где есть массив books со всеми добавленными книгами. Пытаюсь написать метод findBookBy(type, value), который в качестве аргументов будет принимать ключ, по которому будет производиться поиск (тип, автор, название, год выпуска и пр.) и искомое значение. Не могу понять как добраться до самих свойств для сравнения, а также как корректно использовать параметры своего метода findBookBy, помогите пж

class Library {

    constructor(name, books) {

        books = [];
        this.name = name,
        this.books = [];
    }       
    addBook(book) {
        this.books.push(book);   

    }          

    findBookBy(type, value) {                         

    }        

}

const library = new Library("Библиотека имени Ленина");

library.addBook(new DetectiveBook("Артур Конан Дойл", "Полное собрание повестей и рассказов о Шерлоке Холмсе в одном томе", 2019, 1008));
library.addBook(new FantasticBook("Аркадий и Борис Стругацкие", "Пикник на обочине", 1972, 168));
library.addBook(new NovelBook("Герберт Уэллс", "Машина времени", 1895, 138));
library.addBook(new Magazine("Мурзилка", 1924, 60));

  console.log(library.findBookBy("releaseDate", 1924)); //"Мурзилка"

Общая структура

Library {name: 'Библиотека имени Ленина', books: Array(4)}
books
: 
Array(4)
0
: 
DetectiveBook {name: 'Полное собрание повестей и рассказов о Шерлоке Холмсе в одном томе', releaseDate: 2019, pagesCount: 1008, _state: 100, type: 'detective', …}
1
: 
FantasticBook {name: 'Пикник на обочине', releaseDate: 1972, pagesCount: 168, _state: 100, type: 'fantastic', …}
2
: 
NovelBook {name: 'Машина времени', releaseDate: 1895, pagesCount: 138, _state: 100, type: 'novel', …}
3
: 
Magazine {name: 'Мурзилка', releaseDate: 1924, pagesCount: 60, _state: 100, type: 'magazine'}


Ответы (2 шт):

Автор решения: ksa

Не могу понять как добраться до самих свойств для сравнения, а также как корректно использовать параметры своего метода findBookBy

Вот пример как такое можно организовать... Классы DetectiveBook, FantasticBook и т.п. уже на "самостоятельную работу". ;)

//
class Library {
  constructor(name, books = []) {
    this.name = name,
    this.books = books;
  }
  addBook(book) {
    this.books.push(book);
  }
  findBookBy(key, value) {
    return this.books.filter(o => o[key] === value)
  }
}
//
class Book {
  constructor(author, name, release, pages) {
    this.author = author
    this.name = name
    this.release = release
    this.pages = pages
  }
}

const library = new Library("Библиотека имени Ленина");

library.addBook(new Book("Артур Конан Дойл", "Полное собрание повестей и рассказов о Шерлоке Холмсе в одном томе", 2019, 1008));
library.addBook(new Book("Аркадий и Борис Стругацкие", "Пикник на обочине", 1972, 168));
library.addBook(new Book("Герберт Уэллс", "Машина времени", 1895, 138));

console.log(library.findBookBy("release", 1972))

→ Ссылка
Автор решения: Alexander Chernin
class Library {
    constructor(name, books) {
        ...
    }
    // Добавление книги в библиотеку
    add(book) {
        ...
    }
     
    // Поиск книги по заданным параметрам, здесь
    // params это объект параметров поиска {title, genre, ...}
    // Если параметры не заданы, то вернется весь список книг в библиотеке
    findBookBy(params) {
        // Поиск по параметрам        
        return this.books
            // По заголовку книги
            .filter(book => {
                // Если параметр поиска title задан, то сравниваем по нему,
                // иначе пропускаем данный объект для сравнения по другим параметрам
                if (params.title !== undefined) {
                    return params.title === book.title;
                }
                return true;
            )            
            // Сравнение по описанию (смысл кода тот же, но записан короче через тернарный оператор)
            .filter(book => params.description !== undefined ? params.description === book.description: true)
            .filter(book => params.year !== undefined ? params.year === book.year: true)
            .filter(book => params.genre !== undefined? params.genre === book.genre: true);
    }
}

// Класс книги
class Book {
    constructor(genre, title, description, year) {
        this.genre = genre;
        this.title = title;
        ...
    }
}

library.add(new Book('Фантастика', 'Книга 1'));
       .add(new Book('Фантастика', 'Книга 2'));
       .add(new Book('Романы', 'Книга 1'));

// Если ни один из параметров фильтра не задан, то вернутся все книги
library.findBookBy();

// Вернется список книг (2 штуки) с названием "Книга 1"
library.findBookBy({
    title: 'Книга 1'
});

// Вернется одна книга с названием "Книга 1" в жанре "Фантастика"
library.findBookBy({
    title: 'Книга 1',
    genre: 'Фантастика'
});

→ Ссылка