如何从MySQL转换的JSON中优雅生成图表所需命名数组?
优雅实现JSON数组到分组对象的转换
嘿,完全懂你不想手动写一堆数组push的心情——这种重复代码确实不够优雅,而且维护起来麻烦。其实用JavaScript的数组和对象方法就能轻松搞定,给你两种简洁的实现方式:
方法一:用reduce遍历构建(兼容所有场景)
reduce是处理这种结构转换的神器,它可以帮我们一步步累加出目标对象,不管你的原始JSON里有没有缺失字段都能处理:
const myJSON = [ {"name1": "value11", "name2":"value21", "name3": "value31"}, {"name1": "value12", "name2":"value22", "name3": "value32"}, {"name1": "value13", "name2":"value23", "name3": "value33"} ]; const myData = myJSON.reduce((result, currentItem) => { // 把当前对象拆成键值对遍历 Object.entries(currentItem).forEach(([key, value]) => { // 如果结果对象里还没这个key,先初始化空数组 if (!result[key]) { result[key] = []; } // 把当前值推入对应数组 result[key].push(value); }); return result; }, {}); // 初始值是一个空对象 console.log(myData); // 输出就是你想要的:{"name1": ["value11",...], "name2": [...],...}
这个方法的好处是容错性强,哪怕原始数组里有的对象少了某个key,也不会报错,只会跳过缺失的字段。
方法二:用Object.fromEntries+map(简洁高效,适合结构统一的场景)
如果你的原始JSON里所有对象的键都是完全一致的(比如从数据库查出来的结构化数据),这个方法会更简洁:
const myJSON = [ {"name1": "value11", "name2":"value21", "name3": "value31"}, {"name1": "value12", "name2":"value22", "name3": "value32"}, {"name1": "value13", "name2":"value23", "name3": "value33"} ]; // 先获取所有字段名(取第一个对象的键即可) const allKeys = Object.keys(myJSON[0]); // 把每个键对应的值数组打包成键值对,再转成对象 const myData = Object.fromEntries( allKeys.map(key => [key, myJSON.map(item => item[key])]) ); console.log(myData);
这个写法一行核心代码搞定,非常清爽,前提是所有对象的键都完全一致,否则可能会出现undefined值(不过数据库返回的结果一般都是结构统一的,所以这个场景很适用)。
关于MySQL/PDO层面的调整
如果想从数据库层面直接拿到类似结构,其实MySQL本身更擅长返回行数据,强行转成列数组的话需要用GROUP_CONCAT函数,比如:
SELECT GROUP_CONCAT(name1 SEPARATOR ',') AS name1, GROUP_CONCAT(name2 SEPARATOR ',') AS name2, GROUP_CONCAT(name3 SEPARATOR ',') AS name3 FROM your_table;
然后在PHP里把每个字段用explode(',', $value)转成数组再转JSON。但这种方法有局限性:比如GROUP_CONCAT有默认长度限制,而且如果字段值本身包含逗号就会出错,所以还是推荐在JavaScript里处理更灵活可靠。
折腾了这么久能找到优雅的解法应该会轻松很多~
内容的提问来源于stack exchange,提问作者unit303
相关产品推荐
相关产品推荐

