數組中相同屬性值進行分組,支持補全(含區間日期枚舉方法),可實現ant desgin 動態列

數組有多個屬性相同的的對象需要合併爲一個對象,並生成新的數組,用以實現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},
  ...
]

思考:

  1. 需要把tag相同的合併爲一個對象,且用日期做爲key,對應count做爲value
  2. 缺失日期補上,並設置一個默認值

整理下實現的邏輯

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分類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章