简体   繁体   English

将扁平列结构数据更改为分层结构

[英]Change flat column structure data to hierarchical Structure

I am getting a sql resultset in the form of flat data Which is in the following structure 我正在以平面数据的形式获取sql结果集,其结构如下

L0|L1|L2|L3|value

n1|o1|p1|c1|3
n1|o1|p1|c2|2
n1|o1|p2|c1|1
n1|o2|p1|c1|0
n2|o2|p1|c1|5

Here L0,L1,L2,Value.. are column names and we can have more L's as well(it is dynamic) 这里L0,L1,L2,Value ..是列名,我们也可以有更多的L(它是动态的)
I want it to convert into the following form 我希望将其转换为以下形式

[{name:"n1",children:
    [{name:o1,children:
        [{name:"p1",children:
            [{name:"c1",value:3},
            {name:"c2",value:2}]
      },{name:"p2",children:
            [{name:"c1",value:"1"}]
       }],]}.....

I want the result preferably in JSONArray or List structure. 我希望结果最好是JSONArray或List结构。 Does anyone have algo or Code to do that in Java? 有没有人用算法或代码在Java中做到这一点? Thanks 谢谢

Recursion is your friend. 递归是您的朋友。

The code below builds up the hierarchy from the input data into an intermediate model (A tree of "Nodes"). 下面的代码从输入数据到中间模型(“节点”树)构建层次结构。

This is then turned into JSON using a recursive method... 然后使用递归方法将其转换为JSON ...

import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Stack {

    public static void main(String[] args) {
        // Can have as many columns as you want, always assume the last column is the value.
        Object[][] dataFromResultSet = {
                { "n1", "o1", "p1", "c1", 3 },      
                { "n1", "o1", "p1", "c2", 2 },      
                { "n1", "o1", "p2", "c1", 1 },      
                { "n1", "o2", "p1", "c1", 0 },      
                { "n2", "o2", "p1", "c1", 5 }      
        };

        Node root = new Node();

        // Add all records to the hierachy
        for (Object[] row : dataFromResultSet) {
            addToHierachy(root, row);
        }

        // Convert hierachy to JSON
        try {
            JSONArray json = convertToJSON(root);
            System.out.println(json);
        } catch (JSONException e) {
            System.out.println("Something went wrong converting hierachy to JSON");
            e.printStackTrace();
        }
    }

    private static void addToHierachy(Node root, Object[] row) {
        Node current = root;

        // Go through each column in the row
        for(Object col : row) {
            // If this column is a string, then it is a Branch node, not a value one
            // (It might be better to iterate through the array using a counter instead 
            //  and change this condition to say "if it isn't the last column"...)
            if(col instanceof String) {
                // Get (or create) the child node for this column
                current = current.getOrCreateChild((String) col);
            } else {
                // Otherwise, set the value
                current.setValue((Integer) col);
            }
        }
    }

    private static JSONArray convertToJSON(Node root) throws JSONException {
        // Use recursion to build the result JSON
        JSONArray array = new JSONArray();

        // Starting at this root, go through all of the child entries
        for(Map.Entry<String, Node> child : root.getChildren().entrySet()) {
            Node childNode = child.getValue();

            // New object for this entry...
            JSONObject object = new JSONObject();
            // Set the name
            object.put("name", child.getKey());

            // Set the value if it is present on this node
            if(childNode.getValue() != null) {
                object.put("value", childNode.getValue());
            }

            // Generate the child hierarchy if it has children
            if(!childNode.getChildren().isEmpty()) {
                JSONArray childHierachy = convertToJSON(childNode);
                object.put("children", childHierachy);
            }

            array.put(object);
        }

        return array;
    }

    // Class used to build the hierarchy
    static class Node {
        // The map of children, LABEL -> NODE
        private Map<String, Node> children = new HashMap<>();
        // The value (kept as null if this does not have a value set)
        private Integer value;

        public Node getOrCreateChild(String key) {
            Node node = children.get(key);

            if(node == null) {
                node = new Node();
                children.put(key, node);
            }

            return node;
        }

        public Map<String, Node> getChildren() {
            return children;
        }

        public Integer getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }
}

Output: 输出:

[ {
    "name" : "n1",
    "children" : [ {
        "name" : "o2",
        "children" : [ {
            "name" : "p1",
            "children" : [ {
                "name" : "c1",
                "value" : 0
            } ]
        } ]
    }, {
        "name" : "o1",
        "children" : [ {
            "name" : "p2",
            "children" : [ {
                "name" : "c1",
                "value" : 1
            } ]
        }, {
            "name" : "p1",
            "children" : [ {
                "name" : "c1",
                "value" : 3
            }, {
                "name" : "c2",
                "value" : 2
            } ]
        } ]
    } ]
}, {
    "name" : "n2",
    "children" : [ {
        "name" : "o2",
        "children" : [ {
            "name" : "p1",
            "children" : [ {
                "name" : "c1",
                "value" : 5
            } ]
        } ]
    } ]
} ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM