現有一個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,但始終找不到思路
循環,遍歷多次以後感覺腦袋糊掉了,請求各位大大給個思路
女神的闺蜜爱上我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);
}
}
測試結果:
就醬...
滿天的星座2017-06-28 09:26:41
這個不是後端吐出來的嗎?沒必要你去做處理啊,跟後端說下就好啊。或者你就用他們吐的,實現你的效果就好。
無非你想更省事。直接一個循環處理。
用上面的數組,在迴圈裡做處理 跟你處理成後來的 是一樣的。不如前置處理。性能高。下面的是標準的風格。
介面貼出來。
欧阳克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);
寫的不好,如有更優的方法,希望交流交流