Как оптимизировать функцию подсчёта данных?
Всем привет. У меня есть задача написать следующую функцию:
Данные, которые приходят на вход:
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));
Подскажите, как решение можно оптимизировать? |
А по каким критериям оптимизировать?
По количеству символов? По времени исполнения? По объему требуемой памяти? Если работает, и код вам понятен, то что и сколько вы хотите выиграть от оптимизации? |
Цитата:
|
Ну а по мелочам...
Ну введите 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 сек, то наверно имеет смысл оптимизировать. |
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>
|
рони
Порядок элементов в массиве другой. Сначала должны быть элементы с датами, потом total. А итоговые products, fade, water в одном объекте Так вроде в ТЗ |
voraa,
ок, не доглядел. |
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>
|
dc65k, За такую структуру на выходе надо по рукам бить сразу
написание правильных форматов и структур данных - один из факторов, который должен обладать программист. Структуры и данные, должны быть понятны и читабельны. Вы же загнали разные типы данных в массив, с которым и работать после будет не совсем удобно :cray: |
Цитата:
Согласен что фигня полная... Но просто как упражнение с некой долей сложности. |
| Часовой пояс GMT +3, время: 05:20. |