Поиск по модулю данных авторов / книг по lang с использованием JavaScript .map () и .filter () - PullRequest
0 голосов
/ 28 октября 2018

Я бы хотел найти следующий модуль данных по языку books.lang, используя .map() и .filter().Если язык не определен, функция возвращает всех авторов с относительными книгами.Если запрашивается язык, функция возвращает только авторов, у которых есть книги, переведенные на этот язык.

Модуль данных имеет следующий вид:

// data.js
const authors = [
  {
    id: 1,
    name: "Author 1"
  },
  {
    id: 2,
    name: "Author 2"
  },
  {
    id: 3,
    name: "Author 3"
  }
];

const books = [
  {
    id: 1,
    authorId: 1,
    lang: "IT",
    title: "Title 1",
    date: "2018-06-07"
  },
  {
    id: 2,
    authorId: 1,
    lang: "EN",
    title: "Title 2",
    date: "2018-06-07"
  },
  {
    id: 3,
    authorId: 2,
    lang: "IT",
    title: "Title 1",
    date: "2018-06-07"
  },
  {
    id: 4,
    authorId: 2,
    lang: "FR",
    title: "Title 2",
    date: "2018-06-07"
  },
  {
    id: 5,
    authorId: 3,
    lang: "IT",
    title: "Title 1",
    date: "2018-07-07"
  }
];

module.exports = { authors, books };

Распространенное решение работает с использованием классического цикла for.Но я не могу найти правильное решение, используя только .map() и .filter() и, в конечном счете, объединяя их в цепочку, оно не группирует книги по автору.Для каждого автора я создаю свойство books для группировки относительных книг.

Классическим рабочим решением является следующее:

const lang = "IT";

filtered_books = books.filter( book => lang !== null ? book.lang == lang : book.lang !== '' ); 

for (let i in authors) {
    authors[i].books = filtered_books.filter( book => book.authorId == authors.id);
}

Вот где я застрял с моим .map() и .filter() решение:

const lang = "IT";

const selectedAuthors = books.filter( book => lang !== null ? book.lang == lang : book.lang !== '' )
                             .map( book => { 
                                 return authors.filter( author => { 
                                     if(author.id == book.authorId) return author.books = book; // Should I push something here?
                             });
                         });

С параметром lang или без него он не группирует полученные книги по автору.

Большое спасибо за любые советы.

1 Ответ

0 голосов
/ 28 октября 2018

Я выгляжу как двухэтапный проход - 1) объединить авторов с их книгами и 2) отфильтровать тех авторов, у которых есть книги на указанном языке.

const authors = [{"id":1,"name":"Author 1"},{"id":2,"name":"Author 2"},{"id":3,"name":"Author 3"}];
const books = [{"id":1,"authorId":1,"lang":"IT","title":"Title 1","date":"2018-06-07"},{"id":2,"authorId":1,"lang":"EN","title":"Title 2","date":"2018-06-07"},{"id":3,"authorId":2,"lang":"IT","title":"Title 1","date":"2018-06-07"},{"id":4,"authorId":2,"lang":"FR","title":"Title 2","date":"2018-06-07"},{"id":5,"authorId":3,"lang":"IT","title":"Title 1","date":"2018-07-07"}];

function findBooks(authors, books, lng) {

  // map over the books and get their books
  const combined = authors.map(author => {
    const filteredBooks = lng
      ? books.filter(book => book.authorId === author.id && book.lang === lng)
      : books.filter(book => book.authorId === author.id)
    return { ...author, books: filteredBooks };
  });

  // if a language has been specified, return only those authors who have books
  // in that language
  return lng ? combined.filter(author => author.books.some(book => book.lang === lng)) : combined;
}

const authorBooks = findBooks(authors, books);
console.log(authorBooks);

const authorBooksLng = findBooks(authors, books, 'EN');
console.log(authorBooksLng);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...