Как оптимизировать функцию подсчёта данных?
Всем привет. У меня есть задача написать следующую функцию:
Данные, которые приходят на вход: 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, время: 15:59. |