首頁  >  問答  >  主體

java - 一個JSONArray的根據裡面的類型轉化為一個新的JSONArray

現有一個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,但始終找不到思路

循環,遍歷多次以後感覺腦袋糊掉了,請求各位大大給個思路

迷茫迷茫2640 天前1040

全部回覆(3)我來回復

  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-28 09:26:41

    按照題主的輸入輸出要求,從一個JSONArray轉換到另一個JSONArray...感覺輸出的JSONArray無非是按照了兩個屬性進行了歸類,其實結構應該類似於Map>,所以我的想法就是把輸入的JSONArray要轉換成Map>的結構即可...而看到我剛才說的依照屬性歸類...那...很顯然...噔噔噔! ! ! ....心中自然浮現了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>的程式碼貼出來...主要就是這個嘛.. .註釋嘛,熟悉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);
        }
    }

    測試結果:

    就醬...

    回覆
    0
  • 滿天的星座

    滿天的星座2017-06-28 09:26:41

    這個不是後端吐出來的嗎?沒必要你去做處理啊,跟後端說下就好啊。或者你就用他們吐的,實現你的效果就好。
    無非你想更省事。直接一個循環處理。
    用上面的數組,在迴圈裡做處理 跟你處理成後來的 是一樣的。不如前置處理。性能高。下面的是標準的風格。
    介面貼出來。

    回覆
    0
  • 欧阳克

    欧阳克2017-06-28 09:26:41

    程式碼位址
    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);

    寫的不好,如有更優的方法,希望交流交流

    回覆
    0
  • 取消回覆