Existing a LIST:
[
{
"type":"呼吸系统",
"illness":"肺气肿",
"quotaName": "血压"
},
{
"type":"呼吸系统",
"illness":"肺气肿",
"quotaName": "血常规"
},
{
"type":"呼吸系统",
"illness":"哮喘",
"quotaName": "血常规"
},
{
"type":"循环系统",
"illness":"高血压",
"quotaName": "心电图"
},
{
"type":"循环系统",
"illness":"高血压",
"quotaName": "心电彩超"
}
]
The list I want:
[
{
"type":"呼吸系统",
"illnessList":[
{
"name":"肺气肿",
"quotaList":[
{
"name":"血压"
},
{
"name":"血常规"
}
]
},
{
"name":"哮喘",
"quotaList":[
{
"name":"血常规"
}
]
}
]
},
{
"type":"循环系统",
"illnessList":[
{
"name":"高血压",
"quotaList":[
{
"name":"心电图"
},
{
"name":"心电彩超"
}
]
}
]
}
]
The original list, all disease systems, diseases, and disease detection indicators are combined
I want to get a list based on type classification, but I still can’t find the idea
Loop, after traversing it many times, I feel my head is confused, please give me some ideas
女神的闺蜜爱上我2017-06-28 09:26:41
According to the input and output requirements of the subject, convert from one JSONArray
to another JSONArray
... It feels like the output JSONArray is just classified according to two attributes. In fact, the structure should be similar to Map<String, Map<String,List<String>>
, so my idea is to convert the input JSONArray
into the structure of Map<String, Map<String,List<String>>
...and Seeing what I just said about classifying according to attributes... then... obviously... thump thump! ! ! ...Java8's Collectors.groupingBy
naturally came to mind... Just do it without thinking groupingBy
The following is my little idea and code:
Since it is object-oriented, I first created an input Bo objectFromDataBo
@Getter
@Setter
public class FromDataBo {
private String type;
private String illness;
private String quotaName;
}
Then there is the output object created according to the output formatToDataBo
(You can ignore the annotated method first...it is just for conversion, you can look at the data structure first)
@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;
}
}
Now that the input and output objects are in place, the most important classification can be done by attributes. I will first post the code that converts it into Map<String, Map<String, List<String>>
... That’s the main thing. ..Comment, if you are familiar with lamdba
, you can probably tell it at a glance... If you are not familiar, just learn more
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()))));
The last is the complete test code and results. The final result
object is the output you needJSONArray
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);
}
}
Test results:
Just so...
滿天的星座2017-06-28 09:26:41
Isn’t this spit out from the backend? There is no need for you to handle it, just tell the backend. Or you can just use what they spit out to achieve your effect.
It’s just that you want to save trouble. Process directly in a loop.
Use the above array and do the processing in the loop, which is the same as what you process later. Not as good as pre-processing. High performance. The following is the standard style.
The interface is posted.
欧阳克2017-06-28 09:26:41
Code address
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);
The writing is not good. If there is a better method, I hope to share it