java - 一个JSONArray的根据里面的类型转化为一个新的JSONArray
迷茫
迷茫 2017-06-28 09:24:41
0
3
1071

现有一个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,但始终找不到思路

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

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(3)
女神的闺蜜爱上我

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

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

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

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

@Getter
@Setter
public 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);
    }
}

测试结果:

就酱...

滿天的星座

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

学霸

代码地址
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);

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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!