Привет, кодеры! 💻
В предыдущем эпизоде этой серии для начинающих я дал вам упражнение, основанное на следующих исходных данных:
const purchases = [
{item: 'socks', amount: 25.98, date: '2022-05-07 09:31:29'},
{item: 'jacket', amount: 145.98, date: '2022-05-17 17:01:09'},
{item: 'cap', amount: 12.99, date: '2022-05-17 17:03:12'},
{item: 'socks', amount: 43.99, date: '2022-06-11 18:24:16'},
{item: 'cap', amount: 13.99, date: '2022-06-11 18:24:16'},
{item: 'jacket', amount: 132.99, date: '2022-06-21 11:21:35'},
{item: 'socks', amount: 13.99, date: '2022-06-23 09:43:28'},
{item: 'socks', amount: 12.99, date: '2022-07-01 13:14:56'},
{item: 'jacket', amount: 132.99, date: '2022-07-03 15:24:24'},
{item: 'cap', amount: 32.99, date: '2022-07-05 11:14:15'},
{item: 'socks', amount: 13.99, date: '2022-07-07 11:14:15'},
];
Создайте список самых продаваемых и самых плохих товаров за каждый месяц.
Лучшие и худшие определяются по выручке, которую они принесли.
Ожидаемый результат:
const topFlops = {
"2022-05": {
top: 'jacket',
flop: 'cap'
},
"2022-06": {
top: 'jacket',
flop: 'cap'
},
"2022-07": {
top: 'jacket',
flop: 'socks'
}
}
Давайте посмотрим, как мы можем реализовать решение.
Пошаговое решение
Во-первых, давайте напишем на простом английском языке, что нам нужно сделать:
- сгруппировать покупки по месяцам и товарам
- получить первый и последний товар каждого месяца и сделать их
top
иflop
.
Звучит неплохо. Давайте напишем набросок нашего кода.
const purchases = [ /* omitted for readability */];
const itemsMonthlyRevenue = getItemsMonthlyRevenue(purchases);
const topFlop = getTopFlopFromMonthlyRevenue(itemsMonthlyRevenue);
getItemsMonthlyRevenue
getItemsMonthlyRevenue
нужно добавить один уровень по сравнению с тем, что мы имели в первом упражнении части II, чтобы хранить месячный доход элементов.
const getItemsMonthlyRevenue = (purchases) => {
let monthlyRevenue = {}
purchases.forEach(function (purchase) {
const purchaseDate = purchase.date.substring(0, 7);
if (monthlyRevenue[purchaseDate] === undefined) {
monthlyRevenue[purchaseDate] = {}
}
monthlyRevenue[purchaseDate][purchase.item] = purchase.amount + (monthlyRevenue[purchaseDate][purchase.item] || 0);
})
return monthlyRevenue;
}
const purchases = [ /* omitted for readability */];
const itemsMonthlyRevenue = getItemsMonthlyRevenue(purchases);
console.log(JSON.stringify(itemsMonthlyRevenue, null, 2));
Основное отличие от первого упражнения части II в том, что monthlyRevenue[purchaseDate]
теперь является объектом, поэтому нам нужно убедиться, что он инициализирован перед обращением к нему.
Давайте запустим его и посмотрим, что мы получим в консоли.
Вывод:
{
"2022-05": {
"socks": 25.98,
"jacket": 145.98,
"cap": 12.99
},
"2022-06": {
"socks": 57.980000000000004,
"cap": 13.99,
"jacket": 132.99
},
"2022-07": {
"socks": 26.98,
"jacket": 132.99,
"cap": 32.99
}
}
Отлично. Переходим к getTopFlopFromMonthlyRevenue
!
getTopFlopFromMonthlyRevenue
.
const getTopFlopFromMonthlyRevenue = (monthlyRevenue) => {
let topFlop = {};
const NAME_IDX = 0;
const REVENUE_IDX = 1;
for (let month in monthlyRevenue) {
// step 1: get an array of item/monthlyRevenue
const productsSales = Object.entries(monthlyRevenue[month]);
// step 2: sort by revenue
productsSales.sort(function (p1, p2) {
return p2[REVENUE_IDX] < p1[REVENUE_IDX] ? 1 : -1;
})
// step 3: fill the topFlop array object
topFlop[month] = ({
flop: productsSales[0][NAME_IDX],
top: productsSales[productsSales.length - 1][NAME_IDX]
})
}
return topFlop;
}
Что здесь происходит?
Каждый месяц содержит список товаров в качестве ключей и выручку в качестве значений, и это то, что мы хотим отсортировать.
Я использую Object.entries
, который возвращает массив кортежей [key, value]
. Пример:
console.log(monthlyRevenue['2022-06']);
// outputs
[
[ "socks", 57.980000000000004 ],
[ "cap", 13.99 ],
[ "jacket", 132.99 ],
]
Теперь мы можем отсортировать этот массив и получить первый и последний элементы, которые будут выходить flop
и top
соответственно.
Собираем все вместе
const getItemsMonthlyRevenue = (purchases) => {
let monthlyRevenue = {}
purchases.forEach(function (purchase) {
const purchaseDate = purchase.date.substring(0, 7);
if (monthlyRevenue[purchaseDate] === undefined) {
monthlyRevenue[purchaseDate] = {}
}
monthlyRevenue[purchaseDate][purchase.item] = purchase.amount + (monthlyRevenue[purchaseDate][purchase.item] || 0);
})
return monthlyRevenue;
}
const getTopFlopFromMonthlyRevenue = (monthlyRevenue) => {
let topFlop = {};
const NAME_IDX = 0;
const REVENUE_IDX = 1;
for (let month in monthlyRevenue) {
const productsSales = Object.entries(monthlyRevenue[month]);
productsSales.sort(function (p1, p2) {
return p2[REVENUE_IDX] < p1[REVENUE_IDX] ? 1 : -1;
})
topFlop[month] = ({
flop: productsSales[0][NAME_IDX],
top: productsSales[productsSales.length - 1][NAME_IDX]
})
}
return topFlop;
}
const purchases = [
{item: 'socks', amount: 25.98, date: '2022-05-07 09:31:29'},
{item: 'jacket', amount: 145.98, date: '2022-05-17 17:01:09'},
{item: 'cap', amount: 12.99, date: '2022-05-17 17:03:12'},
{item: 'socks', amount: 43.99, date: '2022-06-11 18:24:16'},
{item: 'cap', amount: 13.99, date: '2022-06-11 18:24:16'},
{item: 'jacket', amount: 132.99, date: '2022-06-21 11:21:35'},
{item: 'socks', amount: 13.99, date: '2022-06-23 09:43:28'},
{item: 'socks', amount: 12.99, date: '2022-07-01 13:14:56'},
{item: 'jacket', amount: 132.99, date: '2022-07-03 15:24:24'},
{item: 'cap', amount: 32.99, date: '2022-07-05 11:14:15'},
{item: 'socks', amount: 13.99, date: '2022-07-07 11:14:15'},
];
const itemsMonthlyRevenue = getItemsMonthlyRevenue(purchases);
const topFlop = getTopFlopFromMonthlyRevenue(itemsMonthlyRevenue);
console.log(JSON.stringify(topFlop, null, 2));
Надеюсь, это поможет вам, как новичку, понять, как решить задачу.
Счастливого кодинга! ⌨️