---
# System prepended metadata

title: 'Yalla interview: Book Tasks in JavaScript'

---

assume you have array of books with 1M records, eg.:
```json
    {
    "title": "Book title",
    "publishDate": "1-1-2001",
    "categories": ["romantic", "fiction"],
    "author": "Author Name",
    ...
    }
```
and you have an authors list with 100 records, eg.
```json
    {
	"name": "Author Name",
	"birthDate": "1-1-2001",
	"country": "Turkey",
	...
    }
```
* every author name in the books list should have an associated record in the authors list
* some authors might have no books in the list
* things to consider:
    * your code should be efficient and fast
    * for each task, you can use the code written for prev tasks
    * you should write clean, readable, reusable code


your tasks are :
1. write a code that finds the authors that have no books in the books list
2. write a code that returns the total number of books by each author
3. write a code that returns a list of the categories by each author
4. write a code that finds all unique categories among all the authors
5. write a code that returns an array of categories and a list of authors in each category

## Solution:

To efficiently handle the large dataset and perform the tasks, we can use JavaScript's `Map` and `reduce` functions. These data structures and functions are more performant when dealing with large datasets compared to regular loops.

Let's go through each task one by one:

1. Find authors that have no books in the books list:

```javascript
function findAuthorsWithNoBooks(books, authors) {
  const authorsMap = new Map(authors.map((author) => [author.name, false]));

  books.forEach((book) => {
    authorsMap.set(book.author, true);
  });

  const authorsWithNoBooks = [];
  authorsMap.forEach((hasBooks, authorName) => {
    if (!hasBooks) {
      authorsWithNoBooks.push(authorName);
    }
  });

  return authorsWithNoBooks;
}
```

2. Return the total number of books by each author:

```javascript
function getTotalBooksByAuthor(books) {
  const booksCountByAuthor = books.reduce((countMap, book) => {
    countMap.set(book.author, (countMap.get(book.author) || 0) + 1);
    return countMap;
  }, new Map());

  return booksCountByAuthor;
}
```

3. Return a list of categories by each author:

```javascript
function getCategoriesByAuthor(books) {
  const categoriesByAuthor = books.reduce((categoryMap, book) => {
    const { author, categories } = book;
    if (!categoryMap.has(author)) {
      categoryMap.set(author, []);
    }
    categoryMap.get(author).push(...categories);
    return categoryMap;
  }, new Map());

  return categoriesByAuthor;
}
```

4. Find all unique categories among all authors:

```javascript
function getAllUniqueCategories(books) {
  const allCategories = books.reduce((uniqueCategories, book) => {
    book.categories.forEach((category) => {
      if (!uniqueCategories.includes(category)) {
        uniqueCategories.push(category);
      }
    });
    return uniqueCategories;
  }, []);

  return allCategories;
}
```

5. Return an array of categories and a list of authors in each category:

```javascript
function getAuthorsByCategory(books) {
  const authorsByCategory = new Map();

  books.forEach((book) => {
    const { author, categories } = book;

    categories.forEach((category) => {
      if (!authorsByCategory.has(category)) {
        authorsByCategory.set(category, []);
      }
      authorsByCategory.get(category).push(author);
    });
  });

  return Array.from(authorsByCategory.entries());
}
```

Now, you can use these functions to perform the tasks on your dataset. For example:

```javascript
const books = [...]; // Your 1M records array of books
const authors = [...]; // Your 100 records array of authors

const authorsWithNoBooks = findAuthorsWithNoBooks(books, authors);
const totalBooksByAuthor = getTotalBooksByAuthor(books);
const categoriesByAuthor = getCategoriesByAuthor(books);
const allUniqueCategories = getAllUniqueCategories(books);
const authorsByCategory = getAuthorsByCategory(books);
```

## Solution 2

In case the data in Array of object
```javascript
[
    {
    title: 'Book title',
    publishDate: '1-1-2001',
    categories: ['romantic', 'fiction'],
    author: 'Author Name',
    }
]
```
And 
```javascript
[
    {
    name: 'Author Name',
    birthDate: '1-1-2001',
    country: 'Turkey',
    ...
    }
]
```

To accomplish the tasks efficiently and with clean, readable, and reusable code, we can use JavaScript's array methods and objects. Here's a step-by-step solution for each task:

**Task 1: Find authors with no books**

```javascript
function authorsWithNoBooks(books, authors) {
  const authorsWithBooks = new Set(books.map((book) => book.author));
  return authors.filter((author) => !authorsWithBooks.has(author.name));
}

// Usage
const authorsWithNoBooksList = authorsWithNoBooks(booksArray, authorsArray);
console.log(authorsWithNoBooksList);
```

**Task 2: Total number of books by each author**

```javascript
function totalBooksByAuthor(books) {
  const booksByAuthor = {};
  books.forEach((book) => {
    booksByAuthor[book.author] = (booksByAuthor[book.author] || 0) + 1;
  });
  return booksByAuthor;
}

// Usage
const booksByAuthorCount = totalBooksByAuthor(booksArray);
console.log(booksByAuthorCount);
```

**Task 3: List of categories by each author**

```javascript
function categoriesByAuthor(books) {
  const categoriesByAuthor = {};
  books.forEach((book) => {
    const author = book.author;
    if (!categoriesByAuthor[author]) {
      categoriesByAuthor[author] = new Set();
    }
    book.categories.forEach((category) => categoriesByAuthor[author].add(category));
  });
  return categoriesByAuthor;
}

// Usage
const categoriesByAuthorsList = categoriesByAuthor(booksArray);
console.log(categoriesByAuthorsList);
```

**Task 4: Find all unique categories among all authors**

```javascript
function uniqueCategories(books) {
  const allCategories = new Set();
  books.forEach((book) => {
    book.categories.forEach((category) => allCategories.add(category));
  });
  return Array.from(allCategories);
}

// Usage
const uniqueCategoriesList = uniqueCategories(booksArray);
console.log(uniqueCategoriesList);
```

**Task 5: Array of categories and authors in each category**

```javascript
function authorsInEachCategory(books) {
  const authorsInCategory = {};
  books.forEach((book) => {
    book.categories.forEach((category) => {
      if (!authorsInCategory[category]) {
        authorsInCategory[category] = [];
      }
      if (!authorsInCategory[category].includes(book.author)) {
        authorsInCategory[category].push(book.author);
      }
    });
  });
  return authorsInCategory;
}

// Usage
const authorsInEachCategoryList = authorsInEachCategory(booksArray);
console.log(authorsInEachCategoryList);
```

These functions should provide efficient solutions to each task while maintaining clean, reusable code. Please note that these solutions assume that the input data is well-formed and that the required data structures (e.g., booksArray, authorsArray) are already available in your code.