数组中相同属性值进行分组,支持补全(含区间日期枚举方法),可实现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分类

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