02.08.2021, 16:51
|
Аспирант
|
|
Регистрация: 19.05.2020
Сообщений: 46
|
|
Как оптимизировать функцию подсчёта данных?
Всем привет. У меня есть задача написать следующую функцию:
Данные, которые приходят на вход:
const array = [
{
'2021-07-01': {
'products': [1661.28, 229],
},
},
{
'2021-07-02': {
'fare': [66, 78],
'products': 218,
}
},
{
'2021-07-03': {
'fare': 78,
'products': 909.80,
}
},
{
'2021-07-05': {
'water': 840,
'products': 1021.61,
},
},
]
Данные, которые необходимо получить:
[
{ '2021-07-01': '1890.28' },
{ '2021-07-02': '362.00' },
{ '2021-07-03': '987.80' },
{ '2021-07-05': '1861.61' },
{ total: '5101.69' },
{ fare: '222.00', products: '4039.69', water: '840.00' }
]
Функция считает сумму за день, общую сумму, и общую сумму за каждую позицию. В целом, в условии никаких подвохов нет
Моё решение:
const array = [
{
'2021-07-01': {
'products': [1661.28, 229],
},
},
{
'2021-07-02': {
'fare': [66, 78],
'products': 218,
}
},
{
'2021-07-03': {
'fare': 78,
'products': 909.80,
}
},
{
'2021-07-05': {
'water': 840,
'products': 1021.61,
},
},
]
const calculate = array => {
const digits = 2;
let total = 0;
let object = {};
const output = array.reduce((accumulator, currentValue, index, array) => {
const prop = {};
const date = Object.keys(currentValue)[0];
for (const value of Object.keys(currentValue[date])) {
if (!object[value]) {
object[value] = 0;
}
object[value] += sum(currentValue[date][value]);
}
prop[date] = sum(Object.values(currentValue[date]).flat()).toFixed(digits);
total += sum(Object.values(currentValue[date]).flat());
accumulator.push(prop);
if (index === array.length - 1) {
accumulator.push({
total: total.toFixed(digits)
});
}
return accumulator;
}, []);
output.push(Object.keys(object).sort().reduce((accumulator, currentValue) => {
accumulator[currentValue] = object[currentValue].toFixed(digits);
return accumulator;
}, {}));
return output;
};
const sum = input => {
if (Array.isArray(input)) {
return input.reduce((accumulator, currentValue) => accumulator += currentValue, 0);
}
return input;
};
console.log(calculate(array));
Подскажите, как решение можно оптимизировать?
Последний раз редактировалось dc65k, 02.08.2021 в 18:06.
|
|
02.08.2021, 17:12
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
А по каким критериям оптимизировать?
По количеству символов?
По времени исполнения?
По объему требуемой памяти?
Если работает, и код вам понятен, то что и сколько вы хотите выиграть от оптимизации?
|
|
02.08.2021, 17:18
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Сообщение от dc65k
|
В целом, в условии никаких подвохов нет
|
Точно нет? А .flat() зачем?
|
|
02.08.2021, 17:55
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Ну а по мелочам...
Ну введите
let currentDate = currentValue[date];
И замените везде currentValue[date]. Уж больно часто встречается
Строки 42-46 замените на
object[value] = (object[value] || 0) + sum(currentDate[value]);
Уберите строки 55-59, а после строки 62
output.push( {total: total.toFixed(digits)} );
Учтите, что всякие reduce, forEach, map по скорости существенно проигрывают обычному for( ; ; ). Но при разнице в 2-3 мс это не играет ни какой роли. А если в массиве сотни тысяч элементов и разница будет в 2-3 сек, то наверно имеет смысл оптимизировать.
|
|
02.08.2021, 18:02
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,121
|
|
dc65k,
<pre>
<script>
const array = [{
'2021-07-01': {
'products': [1661.28, 229],
},
},
{
'2021-07-02': {
'fare': [66, 78],
'products': 218,
}
},
{
'2021-07-03': {
'fare': 78,
'products': 909.80,
}
},
{
'2021-07-05': {
'water': 840,
'products': 1021.61,
},
},
]
const calculate = array => Object.entries(array.reduce((obj, a) => {
let [key, value] = Object.entries(a)[0], sum = 0;
for (let k in value) {
k in obj || (obj[k] = 0);
let temp = value[k];
if(Array.isArray(temp)) temp = temp.reduce((a, b) => a + b, 0);
obj[k] += temp;
sum += temp
}
obj[key] = sum;
obj.total += sum;
return obj
}, { total: 0 })).map(([a, b]) => ({[a]: b.toFixed(2)}))
document.write(JSON.stringify(calculate(array), "", 1));
</script></pre>
Последний раз редактировалось рони, 02.08.2021 в 18:18.
Причина: заменил flat на Array.isArray()
|
|
02.08.2021, 18:13
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
рони
Порядок элементов в массиве другой.
Сначала должны быть элементы с датами, потом total.
А итоговые products, fade, water в одном объекте
Так вроде в ТЗ
|
|
02.08.2021, 18:21
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,121
|
|
voraa,
ок, не доглядел.
|
|
02.08.2021, 18:37
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,121
|
|
dc65k,
<pre>
<script>
const array = [{
'2021-07-01': {
'products': [1661.28, 229],
},
},
{
'2021-07-02': {
'fare': [66, 78],
'products': 218,
}
},
{
'2021-07-03': {
'fare': 78,
'products': 909.80,
}
},
{
'2021-07-05': {
'water': 840,
'products': 1021.61,
},
},
]
const calculate = array => {
let obj = {}, total = 0
array = array.map(a => {
let [key, value] = Object.entries(a)[0], sum = 0;
for (let k in value) {
k in obj || (obj[k] = 0);
let temp = value[k];
if (Array.isArray(temp)) temp = temp.reduce((a, b) => a + b, 0);
obj[k] += temp;
sum += temp
}
total += sum
return {
[key]: sum.toFixed(2)
}
});
total = total.toFixed(2);
array.push({ total });
for (let k in obj) obj[k] = obj[k].toFixed(2);
array.push(obj);
return array
}
document.write(JSON.stringify(calculate(array), "", 1));
</script></pre>
|
|
03.08.2021, 10:31
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
dc65k, За такую структуру на выходе надо по рукам бить сразу
написание правильных форматов и структур данных - один из факторов, который должен обладать программист. Структуры и данные, должны быть понятны и читабельны.
Вы же загнали разные типы данных в массив, с которым и работать после будет не совсем удобно
|
|
03.08.2021, 11:40
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,225
|
|
Сообщение от Vlasenko Fedor
|
За такую структуру на выходе надо по рукам бить сразу
|
Может это просто упражнение, которое придумали "на скорую руку".
Согласен что фигня полная... Но просто как упражнение с некой долей сложности.
|
|
|
|