Я работаю над проектом, который требует от меня массирования некоторых данных API (показано ниже во фрагменте как «apiData»).Структура данных, которая мне в конечном итоге нужна для библиотеки графиков, которую я использую (Recharts), такова:
[
{ date: '2018-04-24', TSLA: 283.37, AAPL: 250.01 },
{ date: '2018-04-25', AAPL: 320.34 }
]
Я собрал нижеприведенную функцию, и она работает достаточно хорошо, но у меня проблемы с получениемвсе данные, чтобы показать, даже если нет совпадения между датами.В приведенном ниже примере вы заметите, что объект на дату «2018-04-23» в apiData исключен.В идеале финальный ds должен выглядеть следующим образом:
[
{ date: '2018-04-23', TSLA: 285.12 }
{ date: '2018-04-24', TSLA: 283.37, AAPL: 250.01 },
{ date: '2018-04-25', AAPL: 320.34 }
]
Кроме того, возможно, есть более эффективный способ сделать это, но я какое-то время взламывал и не видел лучшего решения на данный момент,Например, forEach не идеален по мере роста набора данных, что будет происходить, когда мне нужно будет строить длинные периоды данных.
Итак, мои вопросы: 1) Как я могу сделатьчто объекты, совпадающие по дате, объединены, а объекты, которые еще не включены, и 2) какой более эффективный способ выполнить эту операцию?
Если у кого-либо есть какие-либо замечания или замечания по поводу моего подхода и как я могу это сделатьулучшить его, я был бы очень признателен.
Вот ссылка на repl , если это более удобно, чем фрагмент кода ниже.
formatChartData = (data) => {
const chartData = data
.reduce((arr, stock) => {
const stockArr = stock.chart.map((item) => {
let chartObj = {};
chartObj.date = item.date;
chartObj[stock.quote.symbol] = item.close;
if (arr.length > 0) {
arr.forEach((arrItem) => {
if (arrItem.date === item.date) {
chartObj = { ...arrItem, ...chartObj };
}
});
}
return chartObj;
});
return stockArr;
}, []);
console.log(chartData)
}
const apiData = [
{
chart: [
{
date: "2018-04-23",
open: 291.29,
close: 285.12,
},
{
date: "2018-04-24",
open: 291.29,
close: 283.37,
},
],
news: [],
quote: {
symbol: "TSLA"
},
},
{
chart: [
{
date: "2018-04-24",
open: 200.29,
close: 250.01,
},
{
date: "2018-04-25",
open: 290.20,
close: 320.34,
},
],
news: [],
quote: {
symbol: "AAPL"
},
}
]
formatChartData(apiData)
РЕДАКТИРОВАТЬ: В итоге я решил использовать решение charlietfl с внутренним forEach, поскольку мне было легче читать, чем два метода Reduce.Последняя функция выглядит так:
const chartData = data
.reduce((map, stock) => {
stock.chart.forEach((chart) => {
const chartObj = map.get(chart.date) || { date: chart.date };
chartObj[stock.quote.symbol] = chart.close;
map.set(chart.date, chartObj);
});
return map;
}, new Map());`