Как оптимизировать функцию фильтрации?
Всем привет, подскажите, как более оптимально отфильтровать данные:
const data = [ { "date": "2020-03-02", "value": "-0.00807736" }, { "date": "2020-03-03", "value": "0.01775831" }, { "date": "2020-03-04", "value": "0.00433390" }, { "date": "2020-03-31", "value": "0.02667099" }, { "date": "2020-04-01", "value": "-0.01370213" }, { "date": "2020-04-02", "value": "0.02922457" }, { "date": "2020-04-03", "value": "0.01015846" }, { "date": "2020-04-06", "value": "0.01984755" }, { "date": "2020-04-07", "value": "0.00296561" }, { "date": "2020-04-08", "value": "0.01393626" }, { "date": "2020-04-09", "value": "0.01132951" }, { "date": "2020-04-10", "value": "-0.00822985" }, { "date": "2020-04-13", "value": "-0.01640604" }, { "date": "2020-05-04", "value": "-0.00000651" }, { "date": "2020-05-05", "value": "-0.00000513" }, { "date": "2020-05-06", "value": "-0.00501929" }, { "date": "2020-05-07", "value": "0.00339571" }, { "date": "2020-05-08", "value": "0.00176003" } ] /* output [ 2020-03-02, 2020-04-01, 2020-05-04, ] */ const filtered = (data) => Object.values(data.reduceRight((accumulator, currentValue) => { accumulator[new Date(currentValue.date).getMonth()] = currentValue.date return accumulator }, {})) console.log(filtered(data)); |
Цитата:
Ты хочешь узнать про первые "обращения" в каждом месяце? |
У тебя filtered возвращает объект, а в примере вывода ты рисуешь массив.
Чего надо то? И по какому критерию оптимизировать? По длине кода? По скорости выполнения? |
"Ты хочешь узнать про первые обращения в каждом месяце?"
Да, верно. |
Функция filtered возвращает массив.
|
Речь об оптимизации алгоритма.
|
Если даты уже отсортированы и формат закреплён, и если уж совсем оптимизировать, то наверное как-то так:
const filter = (data) => { if (!data || !data.length) return []; const firstDate = data[0].date; const result = [ firstDate ]; let lastMonth = firstDate.slice(5, 7); for (let i = 1; i < data.length; i++) { const { date } = data[i]; const month = date.slice(5, 7); if (month > lastMonth) { lastMonth = month; result.push(date); } } return result; } |
Предложу такой вариант...
const data = [ { "date": "2020-03-02", "value": "-0.00807736" }, { "date": "2020-03-03", "value": "0.01775831" }, { "date": "2020-03-04", "value": "0.00433390" }, { "date": "2020-03-31", "value": "0.02667099" }, { "date": "2020-04-01", "value": "-0.01370213" }, { "date": "2020-04-02", "value": "0.02922457" }, { "date": "2020-04-03", "value": "0.01015846" }, { "date": "2020-04-06", "value": "0.01984755" }, { "date": "2020-04-07", "value": "0.00296561" }, { "date": "2020-04-08", "value": "0.01393626" }, { "date": "2020-04-09", "value": "0.01132951" }, { "date": "2020-04-10", "value": "-0.00822985" }, { "date": "2020-04-13", "value": "-0.01640604" }, { "date": "2020-05-04", "value": "-0.00000651" }, { "date": "2020-05-05", "value": "-0.00000513" }, { "date": "2020-05-06", "value": "-0.00501929" }, { "date": "2020-05-07", "value": "0.00339571" }, { "date": "2020-05-08", "value": "0.00176003" } ] /* output [ 2020-03-02, 2020-04-01, 2020-05-04, ] */ const filtered = data => { const o = {} for (let i = 0; i < data.length; i++) { const m = data[i].date.slice(0, 7) if (o[m]) continue o[m] = data[i].date } return Object.values(o) } alert(filtered(data)); |
Цитата:
Если в среднем M сообщений за месяц, то взяв k = sqrt(M), получим O(N / sqrt(M)) вместо (O(N)) при маленьких М, конечно, толку от этого не будет.. Хотя надо заметить, что при малых M и записей всего очень мало (потому как за 100 лет было всего 1200 месяцев, и оптимизировать нечего). Т.е. М, судя по всему, здоровенное. |
Цитата:
|
Часовой пояс GMT +3, время: 16:11. |