您的位置:首页技术文章
文章详情页

java - 一个JSONArray的根据里面的类型转化为一个新的JSONArray

浏览:46日期:2023-10-23 10:38:59

问题描述

现有一个LIST:

[{ 'type':'呼吸系统', 'illness':'肺气肿', 'quotaName': '血压'},{ 'type':'呼吸系统', 'illness':'肺气肿', 'quotaName': '血常规'}, { 'type':'呼吸系统', 'illness':'哮喘', 'quotaName': '血常规'}, { 'type':'循环系统', 'illness':'高血压', 'quotaName': '心电图'}, { 'type':'循环系统', 'illness':'高血压', 'quotaName': '心电彩超'} ]

我想得到的list:

[{ 'type':'呼吸系统', 'illnessList':[{ 'name':'肺气肿', 'quotaList':[ { 'name':'血压' }, { 'name':'血常规' } ]},{ 'name':'哮喘', 'quotaList':[{ 'name':'血常规'} ]} ]},{ 'type':'循环系统', 'illnessList':[{ 'name':'高血压', 'quotaList':[{ 'name':'心电图'},{ 'name':'心电彩超'} ]} ]} ]

原有的list,所有疾病系统和疾病,以及疾病检测指标都是合在一起的

我想根据类型分类得到一个list,但始终找不到思路

循环,遍历多次以后感觉脑袋糊掉了,请求各位大大给个思路

问题解答

回答1:

按照题主的输入输出要求,从一个JSONArray转换到另一个JSONArray...感觉输出的JSONArray无非是按照了两个属性进行了归类,其实结构应该类似于Map<String,Map<String,List<String>>,所以我的想法就是把输入的JSONArray要转化为Map<String, Map<String,List<String>>的结构即可...而看到我刚才说的按照属性归类...那...很显然...噔噔噔!!!...心中自然浮现了Java8的Collectors.groupingBy...直接无脑groupingBy就行了嘛

下面是我的小思路和代码:既然是面向对象,所以我先创建了一个输入的Bo对象FromDataBo

@Getter@Setterpublic class FromDataBo { private String type; private String illness; private String quotaName;}

接着是按照输出格式创建的输出对象ToDataBo (带注释的方法先可以不看...只是转化用的,可以先看数据结构)

@Getter@Setterpublic class ToDataBo { private String type; private List<ToDataIllnessBo> illnessList; /** * map转化为List<ToDataBo> * @param map * @return */ public static List<ToDataBo> createByMap(Map<String, Map<String, List<String>>> map){return map.entrySet().stream().map(ToDataBo::of).collect(Collectors.toList()); } /** * 一个Map.Entry<String, Map<String, List<String>>>对应转化为一个ToDataBo * @param entry * @return */ public static ToDataBo of(Map.Entry<String, Map<String, List<String>>> entry){ToDataBo dataBo = new ToDataBo();dataBo.setType(entry.getKey());dataBo.setIllnessList(entry.getValue().entrySet().stream().map(ToDataIllnessBo::of).collect(Collectors.toList()));return dataBo; }@Getter @Setter static class ToDataIllnessBo{private String name;private List<ToDataQuotaBo> quotaList;/** * 一个Map.Entry<String, List<String>>对应转化为一个ToDataIllnessBo * @param entry * @return */public static ToDataIllnessBo of(Map.Entry<String, List<String>> entry){ ToDataIllnessBo dataIllnessBo = new ToDataIllnessBo(); dataIllnessBo.setName(entry.getKey()); dataIllnessBo.setQuotaList(entry.getValue().stream().map(ToDataQuotaBo::new).collect(Collectors.toList())); return dataIllnessBo;} } @Getter @Setter @AllArgsConstructor static class ToDataQuotaBo {private String name; }}

输入输出对象有了,那就可以进行最重要按属性分类,我先把转化为Map<String,Map<String,List<String>>的代码贴出来...主要就是这个嘛...注释嘛,熟悉lamdba的估计一眼就看出来...不熟悉再多了解哈吧

Map<String, Map<String, List<String>>> collect = fromDataBos.stream().collect(// 按照type分类Collectors.groupingBy(FromDataBo::getType,// 按照type分类后,同一类的数据再按照illness分类Collectors.groupingBy(FromDataBo::getIllness,// 按照type分类,再按照illness分类后,同一类的数据取其中的QuotaName并转化为集合Collectors.mapping(FromDataBo::getQuotaName, Collectors.toList()))));

最后是完整的测试代码和结果,最后的result对象就是你需要的输出JSONArray

public class Test1 { public static void main(String[] args) {String from = '[n' +'{n' +' 'type':'呼吸系统',n' +' 'illness':'肺气肿',n' +' 'quotaName': '血压'n' +'},n' +'{n' +' 'type':'呼吸系统',n' +' 'illness':'肺气肿',n' +' 'quotaName': '血常规'n' +'},n' +' {n' +' 'type':'呼吸系统',n' +' 'illness':'哮喘',n' +' 'quotaName': '血常规'n' +'},n' +' {n' +' 'type':'循环系统',n' +' 'illness':'高血压',n' +' 'quotaName': '心电图'n' +'},n' +' {n' +' 'type':'循环系统',n' +' 'illness':'高血压',n' +' 'quotaName': '心电彩超'n' +'}n' +' ]';// 把输入的JSONArray字符串转化为FromDataBo集合List<FromDataBo> fromDataBos = JSONArray.parseArray(from, FromDataBo.class);// 归类Map<String, Map<String, List<String>>> collect = fromDataBos.stream().collect(// 按照type分类Collectors.groupingBy(FromDataBo::getType,// 按照type分类后,同一类的数据再按照illness分类Collectors.groupingBy(FromDataBo::getIllness,// 按照type分类,再按照illness分类后,同一类的数据取其中的QuotaName并转化为集合Collectors.mapping(FromDataBo::getQuotaName, Collectors.toList()))));// 归类后的map转化为输出对象ToDataBo集合List<ToDataBo> toDataBos = ToDataBo.createByMap(collect);// 我是输出对象,我在这JSONArray result = JSONArray.parseArray(JSONArray.toJSONString(toDataBos));System.out.println(result); }}

测试结果:

java - 一个JSONArray的根据里面的类型转化为一个新的JSONArray

就酱...

回答2:

这个不是后端吐出来的吗?没必要你去做处理啊,跟后端说下就好啊。或者你就用他们吐的,实现你的效果就好。无非你想更省事。直接一个循环处理。用上面的数组,在循环里做处理 跟你处理成后来的 是一样的。不如前置处理。性能高。下面的是标准的风格。界面贴出来。

回答3:

代码地址http://jsbin.com/roqejoficu/e...

var convertData = function(data){ let result = []; var level1Obj = {}; var level2Obj = {}; var level3Obj = {}; data.forEach(function (item, index, arr) {//一层对象level1Obj[item.type] = {};level1Obj[item.type]['type'] = item.type;//2层对象level2Obj[item.type+item.illness] = {};level2Obj[item.type+item.illness]['p1'] = item.type;level2Obj[item.type+item.illness]['type'] = item.illness;//3层对象level3Obj[index] = {};level3Obj[index]['p1'] = item.type;level3Obj[index]['p2'] = item.illness;level3Obj[index]['type'] = item.quotaName; });for (var level1 in level1Obj) {var o1 = {};o1.type = level1Obj[level1].type;o1.list = [];result.push(o1);for (var level2 in level2Obj) { if (level2Obj[level2].p1 == level1Obj[level1].type) {var o2 = {};o2.type = level2Obj[level2].type;o2.list = [];o1.list.push(o2);for (var level3 in level3Obj) { if (level3Obj[level3].p1 == level1Obj[level1].type && level3Obj[level3].p2 == level2Obj[level2].type) {var o3 = {};o3.type = level3Obj[level3].type;o2.list.push(o3); }} }} } console.log(result); return result;},var result = convertData(data);

写的不好,如有更优的方法,希望交流交流

标签: java
相关文章: