數組有多個屬性相同的的對象需要合併爲一個對象,並生成新的數組,用以實現ant desgin 的動態列功能。
原數據:
[
{ count: 289, tag: '連網失敗', typeName: '2020-04-23' },
{ count: 307, tag: '連網失敗', typeName: '2020-04-25' },
...
]
需要數據:
[
{ tag: '連網失敗', '2020-04-23': 289, '2020-04-24': 0, '2020-04-25': 307},
...
]
思考:
- 需要把tag相同的合併爲一個對象,且用日期做爲key,對應count做爲value
- 缺失日期補上,並設置一個默認值
整理下實現的邏輯
const dates = [
'2020-04-20',
'2020-04-21',
'2020-04-22',
'2020-04-23',
'2020-04-24',
'2020-04-25',
'2020-04-26',
'2020-04-27',
'2020-04-28',
'2020-04-29',
];
const lineData = [
{ count: 289, tag: '連網失敗', typeName: '2020-04-23' },
// { count: 293, tag: '連網失敗', typeName: '2020-04-24' },
{ count: 307, tag: '連網失敗', typeName: '2020-04-25' },
{ count: 309, tag: '連網失敗', typeName: '2020-04-26' },
{ count: 289, tag: '連網失敗', typeName: '2020-04-27' },
{ count: 129, tag: '機器壞了', typeName: '2020-04-23' },
{ count: 113, tag: '機器壞了', typeName: '2020-04-24' },
// { count: 105, tag: '機器壞了', typeName: '2020-04-25' },
{ count: 106, tag: '機器壞了', typeName: '2020-04-26' },
{ count: 116, tag: '機器壞了', typeName: '2020-04-27' },
{ count: 75, tag: '無法開機', typeName: '2020-04-23' },
{ count: 89, tag: '無法開機', typeName: '2020-04-24' },
{ count: 90, tag: '無法開機', typeName: '2020-04-25' },
// { count: 114, tag: '無法開機', typeName: '2020-04-26' },
{ count: 92, tag: '無法開機', typeName: '2020-04-27' },
];
/**
*
* @param {* 要轉換的數組} objectArray
* @param {* 分組字段} property
* @param {* 默認展示個數,不夠則補全} dates
*/
function groupBy(objectArray, property, dates) {
const groupedPeople = objectArray.reduce((acc, obj) => {
const key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
const obj2 = {
[obj.typeName]: obj.count,
tag: obj.tag,
};
acc[key].push(obj2);
return acc;
}, {});
const list = Object.values(groupedPeople)
.map(item => {
const obj = {};
item.map(child => {
obj[property] = child[property];
for (const key in child) {
if (key !== property) {
const element = child[key];
obj[key] = element;
}
}
return obj;
});
const b = Object.keys(obj).filter(item => item !== property);
const difference = dates.filter(v => !dates.includes(v) || !b.includes(v));
// console.log(dates, b, difference);
difference.forEach(element => {
obj[element] = 0;
});
return [obj];
})
.flat();
return list;
}
/**
* 枚舉兩個時間段中的日期
* @param {*} startDate
* @param {*} endDate
*/
const enumerateDaysBetweenDates = (startDate, endDate) => {
const dates = [];
const currDate = moment(startDate).subtract(1, 'days').startOf('day');
const lastDate = moment(endDate).startOf('day');
while (currDate.add(1, 'days').diff(lastDate) < 0) {
const formatCurrDate = moment(currDate.clone().toDate()).format('YYYY-MM-DD');
dates.push(formatCurrDate);
}
return dates;
};
var groupedPeople = groupBy(lineData, 'tag', dates);
console.log(groupedPeople);
動態生成列的關鍵代碼
const columns = useMemo(() => {
if (data.length) {
const header = data[0];
const keys = ['tag'].concat(
Object.keys(header)
.filter(item => item !== 'tag')
.sort()
); // 按日期排序
const newColumns = keys.map(item => {
const obj = { title: null, dataIndex: null, key: null };
obj.title = item === 'tag' ? '標籤' : item;
obj.width = item === 'tag' ? 100 : 'auto';
obj.dataIndex = item;
obj.key = item;
return obj;
});
return newColumns;
}
return [];
}, [data]);
參考: MDN 按屬性對object分類