[英]convert array of objects to nested array of arrays for building chart
我有以下數組
const data = [
{
date: "2018-01-01",
label: "MH",
qt: 10
},
{
date: "2018-04-01",
label: "MH",
qt: 30
},
{
date: "2018-02-01",
label: "GJ",
qt: 30
},
{
date: "2018-03-01",
label: "KL",
qt: 30
},
{
date: "2018-02-01",
label: "KL",
qt: 40
}
]
我希望我的輸出是
[
[date,MH,GJ,KL],
['Jan 2018',10,null,null],
['Feb 2018',null,30,40],
['Mar 2018',null,null,30],
['Apr 2018',30,null,null]
]
我怎樣才能以優化的方式實現這一目標? 並且日期應該按順序排序。 我試着做
data.sort(function compare(a, b) {
var dateA = new Date(a.date);
var dateB = new Date(b.date);
return dateA - dateB;
});
let labelArr = data.map(l => l.label);
let dateArr = data.map(l => l.date);
labelArr = _.uniq(labelArr);
dateArr = _.uniq(dateArr);
console.log(labelArr, dateArr);
const outputArr = [];
dateArr.forEach(d => {
labelArr.forEach(l => {
const tempObj = data.filter(r => {
if (d == r.date && l == r.label) {
return r;
}
else {
return { date: d, label: l, qt: null }
}
})
outputArr.push(tempObj);
});
});
但我被困在這里。 我在想的是,首先我將為不存在的日期和標簽創建對象,並將其 qt 添加到 null。 之后我將按日期分組,然后只將 qt 插入到結果中
您可以使用一個對象來保存每個日期的數組,並使用一個對象來跟蹤列的索引。
最后,對於未設置的項目,將所有元素設置為null
。
var data = [{ date: "2018-01-01", label: "MH", qt: 10 }, { date: "2018-04-01", label: "MH", qt: 30 }, { date: "2018-02-01", label: "GJ", qt: 30 }, { date: "2018-03-01", label: "KL", qt: 30 }, { date: "2018-02-01", label: "KL", qt: 40 }], cols = {}, rows = {}, result = data .sort(({ date: a }, { date: b }) => a > b || -(a < b)) .reduce((r, { date, label, qt }) => { date = date.slice(0, 7); if (!rows[date]) r.push(rows[date] = [date]); if (!cols[label]) cols[label] = r[0].push(label) - 1; rows[date][cols[label]] = (rows[date][cols[label]] || 0) + qt; return r; }, [['date']]) .map((a, _, [{ length }]) => Array.from({ length }, (_, i) => a[i] || null)); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我不知道這是否是最好的解決方案,但它是一個有效的解決方案:
const data = [{ date: "2018-01-01", label: "MH", qt: 10 }, { date: "2018-04-01", label: "MH", qt: 30 }, { date: "2018-02-01", label: "GJ", qt: 30 }, { date: "2018-03-01", label: "KL", qt: 30 }, { date: "2018-02-01", label: "KL", qt: 40 } ] function formatData(data) { const labels = {}; const map = {}; data .sort((a, b) => a.date < b.date ? -1 : 1) .forEach(item => { const date = moment(item.date).format('MMM YYYY'); labels[item.label] = true; if (map[date]) { map[date][item.label] = item.qt; } else { map[date] = { [item.label]: item.qt }; } }); const labelsArr = Object.keys(labels); const formattedData = Object.keys(map).map(date => { const values = labelsArr.map(label => map[date][label] || null); return [date, ...values]; }); return [['date', ...labelsArr], ...formattedData]; } const result = formatData(data); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://momentjs.com/downloads/moment.min.js"></script>
我嘗試這樣做:
data.sort(function compare(a, b) {
var dateA = new Date(a.date);
var dateB = new Date(b.date);
return dateA - dateB;
});
let labelArr = data.map(l => l.label);
let dateArr = data.map(l => l.date);
labelArr = _.uniq(labelArr);
dateArr = _.uniq(dateArr);
const outputArr = [['Date', ...labelArr]];
dateArr.forEach(d => {
const o1 = data.filter(e => e.date == d)
const o2 = o1.reduce((s, a) => {
s[a.label] = a.qt;
return s;
}, {})
const b1 = []
labelArr.forEach(l => {
b1.push(o2[l])
});
outputArr.push([moment(d).format('MMM YYYY'), ...b1]);
});
希望它可以幫助某人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.