Домашнє завдання #11: Кіноаналітика — вижми все з датасету
Уяви: тебе взяли аналітиком у стрімінговий сервіс. Перше завдання від боса — «ось дані по фільмах, до вечора хочу знати: що в нас найкраще, хто найкасовіший режисер і що порадити глядачу на вечір». Справжні дата-аналітики роблять це тими самими map/filter/reduce, які ти вивчив. Час і тобі.
Датасет
Скопіюй масив у свій script.js без змін — усі очікувані результати нижче пораховані саме для нього:
const movies = [
{ title: "Темний лицар", year: 2008, genre: "бойовик", rating: 9.0, boxOffice: 1006, director: "Крістофер Нолан" },
{ title: "Початок", year: 2010, genre: "фантастика", rating: 8.8, boxOffice: 837, director: "Крістофер Нолан" },
{ title: "Інтерстеллар", year: 2014, genre: "фантастика", rating: 8.7, boxOffice: 701, director: "Крістофер Нолан" },
{ title: "Оппенгеймер", year: 2023, genre: "драма", rating: 8.3, boxOffice: 976, director: "Крістофер Нолан" },
{ title: "Матриця", year: 1999, genre: "фантастика", rating: 8.7, boxOffice: 467, director: "Лана і Ліллі Вачовскі" },
{ title: "Форрест Ґамп", year: 1994, genre: "драма", rating: 8.8, boxOffice: 678, director: "Роберт Земекіс" },
{ title: "Паразити", year: 2019, genre: "драма", rating: 8.5, boxOffice: 263, director: "Пон Джун Хо" },
{ title: "Аватар", year: 2009, genre: "фантастика", rating: 7.9, boxOffice: 2923, director: "Джеймс Кемерон" },
{ title: "Титанік", year: 1997, genre: "драма", rating: 7.9, boxOffice: 2264, director: "Джеймс Кемерон" },
{ title: "Джокер", year: 2019, genre: "драма", rating: 8.4, boxOffice: 1074, director: "Тодд Філліпс" },
{ title: "Вовк з Волл-стріт", year: 2013, genre: "драма", rating: 8.2, boxOffice: 407, director: "Мартін Скорсезе" },
{ title: "Гладіатор", year: 2000, genre: "бойовик", rating: 8.5, boxOffice: 465, director: "Рідлі Скотт" },
{ title: "Шалений Макс: Дорога люті", year: 2015, genre: "бойовик", rating: 8.1, boxOffice: 380, director: "Джордж Міллер" },
{ title: "Король Лев", year: 1994, genre: "анімація", rating: 8.5, boxOffice: 968, director: "Роджер Аллерс і Роб Мінкофф" },
{ title: "Захар Беркут", year: 2019, genre: "бойовик", rating: 6.7, boxOffice: 1.5, director: "Ахтем Сеітаблаєв" },
{ title: "Мавка. Лісова пісня", year: 2023, genre: "анімація", rating: 6.9, boxOffice: 21, director: "Олег Маламуж і Олександра Рубан" },
{ title: "Памфір", year: 2023, genre: "драма", rating: 7.1, boxOffice: 0.2, director: "Дмитро Сухолиткий-Собчук" },
];
boxOffice — світова каса в мільйонах доларів. Так, «Аватар» справді зібрав майже 3 мільярди. І так, тут є українські фільми — аналітика без «Мавки» і «Захара Беркута» була б неповною.
Головне правило: жодного циклу for/while. Тільки методи масивів — це окремий критерій на 15 балів.
Завдання: 7 функцій
1. topRated(movies, n) — топ-n за рейтингом
Повертає масив назв n найрейтинговіших фільмів (від найвищого). Порядок фільмів з однаковим рейтингом — неважливий. Оригінальний масив не змінюється!
| Виклик | Результат |
|---|---|
topRated(movies, 5) | ["Темний лицар", "Початок", "Форрест Ґамп", "Інтерстеллар", "Матриця"] |
topRated(movies, 3) | ["Темний лицар", "Початок", "Форрест Ґамп"] |
2. releasedAfter(movies, year) — новинки
Масив фільмів (об'єктів), випущених строго після зазначеного року.
| Виклик | Результат |
|---|---|
releasedAfter(movies, 2018) | 6 фільмів: Оппенгеймер, Паразити, Джокер, Захар Беркут, Мавка. Лісова пісня, Памфір |
releasedAfter(movies, 2023) | [] |
3. boxOfficeByGenre(movies) — каса по жанрах
Через reduce збери об'єкт { жанр: сумарна каса } (порядок ключів — неважливий):
boxOfficeByGenre(movies);
// { "бойовик": 1852.5, "фантастика": 4928, "драма": 5662.2, "анімація": 989 }
4. directorRating(movies, director) — середній рейтинг режисера
Число, округлене до 2 знаків. Якщо режисера в датасеті немає — рядок "Режисера не знайдено".
| Виклик | Результат |
|---|---|
directorRating(movies, "Крістофер Нолан") | 8.7 |
directorRating(movies, "Джеймс Кемерон") | 7.9 |
directorRating(movies, "Стівен Спілберг") | "Режисера не знайдено" |
5. bestYear(movies) — найприбутковіший рік
Об'єкт { year, total } — рік із найбільшою сумарною касою:
bestYear(movies);
// { year: 2009, total: 2923 }
6. searchByTitle(movies, query) — пошук
Масив фільмів, у назві яких є підрядок query. Регістр — неважливий.
| Виклик | Результат |
|---|---|
searchByTitle(movies, "ар") | 2 фільми: Аватар, Захар Беркут |
searchByTitle(movies, "МАВ") | 1 фільм: Мавка. Лісова пісня |
searchByTitle(movies, "хоббіт") | [] |
7. recommend(movies, genre, minRating) — порадник на вечір
Випадковий фільм (об'єкт) заданого жанру з рейтингом строго вище minRating. Якщо кандидатів немає — рядок "Нічого не знайдено".
| Виклик | Результат |
|---|---|
recommend(movies, "драма", 8.4) | випадково: Форрест Ґамп або Паразити |
recommend(movies, "анімація", 9) | "Нічого не знайдено" |
Бонус (+10): Pipeline «топ-3 драми 2010-х за касою»
Функція top3DramasOf2010s(movies) — один ланцюжок методів (без проміжних змінних): відфільтрувати драми 2010–2019 років → відсортувати за касою (спадання) → взяти перші 3 → повернути масив назв.
top3DramasOf2010s(movies);
// ["Джокер", "Вовк з Волл-стріт", "Паразити"]
Підказки
Рівень 1: напрямок думки
- Кожна функція — це комбінація 1–3 методів: спершу відбери потрібне (
filter), потім перетвори (map) або згорни в одне значення (reduce) - «Найкращий рік» — це два кроки: спершу зведи касу по роках в об'єкт (як у жанрах), потім знайди ключ із максимальним значенням
- Випадковий елемент масиву — випадковий індекс від 0 до довжини
Рівень 2: які методи використати
sortмутує масив — сортуй копію:[...movies].sort((a, b) => b.rating - a.rating)- Пошук без регістру:
title.toLowerCase().includes(query.toLowerCase()) - Округлення до 2 знаків:
Math.round(avg * 100) / 100 - Максимум серед пар ключ-значення:
Object.entries(totals)дає масив пар — його теж можна прогнати черезreduce - Перші n елементів:
slice(0, n)
Рівень 3: псевдокод boxOfficeByGenre
функція boxOfficeByGenre(movies):
повернути movies.reduce((acc, movie) => {
якщо в acc ще немає ключа movie.genre → створити його зі значенням 0
додати movie.boxOffice до acc[movie.genre]
повернути acc
}, порожній об'єкт)
Як здати
- Робота — в публічному GitHub-репозиторії курсу
my-web-course, у папціhw-11/ - У папці:
script.js(датасет + 7 функцій + демо-виклик кожної зconsole.log) таindex.html-обгортка:
<!DOCTYPE html>
<html lang="uk">
<head><meta charset="UTF-8"><title>HW-11</title></head>
<body>
<script src="script.js"></script>
</body>
</html>
- Відкрий
index.html→ консоль (F12): звіт для боса готовий - У папці —
README.md: 2-3 речення що зроблено + як запустити - Мінімум 3 коміти з осмисленими повідомленнями (не «fix» та «update»)
- Надішли посилання на репозиторій у форму на цій сторінці
Критерії оцінки
| Критерій | Тип | Бали |
|---|---|---|
topRated — правильний топ, оригінальний масив не мутується | [код] | 10 |
releasedAfter — строга нерівність, збігається з прикладами | [код] | 10 |
boxOfficeByGenre — reduce в об'єкт, точні суми | [код] | 15 |
directorRating — середнє з округленням + випадок «не знайдено» | [код] | 10 |
bestYear — об'єкт { year, total }, збігається з прикладом | [код] | 15 |
searchByTitle — пошук підрядка без урахування регістру | [код] | 10 |
recommend — фільтр за жанром і рейтингом + випадковий вибір + «не знайдено» | [код] | 10 |
Жодного for/while — тільки методи масивів | [код] | 15 |
| Контракт здачі: 3+ осмислені коміти, README, демо-виклики | [код] | 5 |
Бонус: pipeline top3DramasOf2010s одним ланцюжком | [код] | +10 |
Що далі
Цей стиль — фільтри, сортування, трансформації даних — рівно те, чим ти займатимешся в React (Block 8): там список фільмів рендериться через той самий map. А в ДЗ #16 ти завантажиш такі дані вже не з константи, а з реального API.