侧边栏壁纸
博主头像
神奇的程序员

今天的努力只为未来

  • 累计撰写 170 篇文章
  • 累计创建 27 个标签
  • 累计收到 226 条评论

目 录CONTENT

文章目录

JSON数据归类的实现

神奇的程序员
2020-05-20 / 0 评论 / 4 点赞 / 707 阅读 / 2,502 字 正在检测是否收录...

前言

今天在写业务代码时,遇到了表格归类的一个需求,刚开始以为很简单,但是真正上手实现时,发现还是有一点点难度的。

本文将以上述问题为背景,讲解JSON数据归类的实现,欢迎各位感兴趣的开发者阅读本文。

问题背景

如下图所示,需要将图一的表格转成图二的表格。

实现思路

观察上图后我们发现,这个问题可以描述为:将姓名相同的数据合并到一起。

我们的解决方案为:通过数据来渲染dom。

  • 获取DOM表格内的数据将其转换为JSON
  • 对获取的表格JSON数据根据姓名字段进行归类
  • 将归类好的JSON数据重新渲染成DOM表格

实现代码

获取DOM表格内的数据将其转换为JSON,将归类好的JSON重新渲染成DOM表格不是本文的重点,所以此处不予实现。

此处重点讲解JSON数据归类的实现。

  • 将DOM表格转换成JSON后的数据如下
[
    {
        "name": "李四",
        "title": "鸡腿",
        "bookingUnit": "4",
        "measUnit": "",
        "unitPrice": "5",
        "totalPrice": "20"
    },
    {
        "name": "张三",
        "title": "牛奶",
        "bookingUnit": "5",
        "measUnit": "",
        "unitPrice": "10",
        "totalPrice": "50"
    },
    {
        "name": "李四",
        "title": "口蘑",
        "bookingUnit": "3",
        "measUnit": "",
        "unitPrice": "4",
        "totalPrice": "12"
    },
    {
        "name": "王五",
        "title": "蘑菇",
        "bookingUnit": "3",
        "measUnit": "",
        "unitPrice": "4",
        "totalPrice": "12"
    },
    {
        "name": "王五",
        "title": "牛肉",
        "bookingUnit": "13",
        "measUnit": "",
        "unitPrice": "14",
        "totalPrice": "112"
    }
]
  • 归类好的JSON数据如下
[
  {
    "name": "李四",
    "children": [
      {
        "title": "鸡腿",
        "bookingUnit": "4",
        "measUnit": "",
        "unitPrice": "5",
        "totalPrice": "20"
      },
      {
        "title": "口蘑",
        "bookingUnit": "3",
        "measUnit": "",
        "unitPrice": "4",
        "totalPrice": "12"
      }
    ]
  },
  {
    "name": "张三",
    "children": [
      {
        "title": "牛奶",
        "bookingUnit": "5",
        "measUnit": "",
        "unitPrice": "10",
        "totalPrice": "50"
      }
    ]
  },
  {
    "name": "王五",
    "children": [
      {
        "title": "蘑菇",
        "bookingUnit": "3",
        "measUnit": "",
        "unitPrice": "4",
        "totalPrice": "12"
      },
      {
        "title": "牛肉",
        "bookingUnit": "13",
        "measUnit": "",
        "unitPrice": "14",
        "totalPrice": "112"
      }
    ]
  }
]

实现归类函数

经过上述分析后,我们面临的问题是:将获取到DOM表格的JSON数据转换为我们最终渲染DOM需要的数据。

所以,我们要实现一个JSON归类函数,思路如下:

  • 声明一个函数,参数为一个JSON数组
  • 函数内部声明一个数组,用于存放归类好的数据
  • 函数内部声明一个对象,用于存放已经遍历过的元素。
  • 遍历传进来的JSON数组
  • 判断当前遍历到的元素是否存在于已经遍历过的元素对象中
  • 如果不存在,将当前遍历到的元素对象放进已经归类好的数组中,将当前遍历的对象放进已遍历元素对象中
  • 如果存在,遍历归类好数据,如果遍历到的元素等于当前元素对象,则将当前元素对象放进遍历到的元素children数组中,结束当前循环,继续下一轮。
  • 返回归类好的JSON数据

我们将上述思路转换为代码

/**
 * JSON归类 根据特定条件,将同类数据归类到一起
 * @param arr
 * @returns {[]}
 * @constructor
 */
const JsonClassification = (arr) => {
    // 存放最终归类好的数据
    const resultData = [];
    // 存放已经遍历过的元素
    const temp = {};
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        const itemObj = {
            title: item.title,
            bookingUnit: item.bookingUnit,
            measUnit: item.measUnit,
            unitPrice: item.unitPrice,
            totalPrice: item.totalPrice
        }
        // 判断当前key是否在已经遍历过的元素对象里
        if (!temp[item.name]) {
            resultData.push({
                name: item.name,
                children: [itemObj]
            });
            // 将当前key放进已经遍历过的元素对象中
            temp[item.name] = item;
        } else {
            // 遍历归类好的数据,将当前遍历到的数据放进与之对应的分类中
            for (let j = 0; j < resultData.length; j++) {
                let resultItem = resultData[j];
                if (resultItem.name === item.name) {
                    resultItem.children.push(itemObj);
                    break;
                }
            }
        }
    }
    return resultData;
}

执行结果如下,数据满足了我们的需求,将归类好的json数据渲染成table表格就完美的解决了文章开头遇到的问题了。

更多实现方法

群友 @lipd 使用reduce实现了JSON归类函数,代码量比我的实现方式少了很多,感兴趣的开发者可以看看他的实现(如下图所示)

写在最后

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于掘金,未经许可禁止转载💌
4

评论区