使用列表/表中的json创建树 [英] Creating a tree using json from a list/table

查看:126
本文介绍了使用列表/表中的json创建树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设在这种情况下我有这样的表/列表n = 3,但是n可以是无限制的。

Let’s say I have table/list like this n=3 in this case, but n can be as unlimited.

groupid       answerid1     answerid2     answerid(n)
1              3            6             8 
1              3            6             9 
1              4            7               
2              5                            

我想创建一个父/子树json像这样输出使用java。(我一直在使用GSON)

and i want to create a parent/child tree json output like this using java.(I have been using GSON)

    {
        data: [
            {
                groupid: 1,
                children: [
                    {
                        answerid1: 1,
                        children: [
                            {
                                answerid2:3,
                                children: [
                                           {
                                    answerid3:6,
                                                  children: [
                                                              {answerid4: 8},
                                  {answerid4: 9} 
                                                             ]
                                              } 


                            }, {
                                 answerid2: 4,
                                 children: [
                                          {answerid3:7} 
                                   ]
                                 }
                                ]         
                    }, 

               {
                 groupid1: 2,
                 children: [
                       { answerid2: 5}
                        ]
                }

               ]      
        }

这样做的代码/步骤是什么。我查看了很多标签,但大多数人都在打印输出,而不是递归地为GSON构建一个hashmap / ArrayList来解析adn写入API。另一点每个id都有与之关联的其他数据,这些数据必须包含在json输出中。例如,代替{groupid:1}需要这个{groupid:1,text = toyota}。

what would be the code/steps to do so. i have looked through lots of tags but mostly people are printing the output and not recursively build a hashmap/ArrayList for GSON to parse adn write to API. one other point each id has other data associated with it that will have to be included in the json output. for instance instead of {groupid:1} would need to this {groupid:1, text=toyota}.

任何帮助都非常感谢,因为我对java很新因为我来自SAS背景。

any help is greatly appreciated as i am fairly new to java as i come from SAS background.

我得到这样的数据(只是一个列表矩阵)
Toyota,Gas,Compact,Corolla


  • Toyota,Gas,Compact ,凯美瑞

  • Toyota,Hybrid,Compact,Prius

  • Honda,Gas,Compact,Civic
  • I get data like this (just a matrix of list) Toyota, Gas, Compact, Corolla

  • Toyota, Gas, Compact, Camry
  • Toyota, Hybrid, Compact, Prius
  • Honda, Gas, Compact, Civic
  • 如果需要我可以将数据重新分成两个表格

    If needed I can REFORMAT THE DATA into two tables

    parentId parText answerId


  • 1丰田1

  • 1丰田2

  • 1丰田3

  • 2本田4
  • parentId parText answerId

  • 1 Toyota 1
  • 1 Toyota 2
  • 1 Toyota 3
  • 2 Honda 4
  • answerId等级answerTextid answerText


  • 1 1 1 Gas

  • 1 2 2 Compact

  • 1 3 3 Corolla

  • 2 1 1 Gas

  • 2 2 2 Compact

  • 2 3 4凯美瑞

  • ...

    answerId level answerTextid answerText

  • 1 1 1 Gas
  • 1 2 2 Compact
  • 1 3 3 Corolla
  • 2 1 1 Gas
  • 2 2 2 Compact
  • 2 3 4 Camry
  • 然后我需要把它变成一棵树(像父亲/孩子一样的JSON节目的嵌套输出 - 就像是你是creatign文件系统目录)

    Then I need to make it a tree(nested output like the JSON shows with parent/children - just like if you were creatign a file system directory)

    另一个我想做的是每辆车都有里程数作为变种({answerid3:4,text = Corolla,mileage = 38}。但如果我遍历树,则给分支平均一英里。就像在分公司丰田,Gas,Compact一样,里程将是平均值(凯美瑞,卡罗拉)

    one other thign i would like to do is for each car have mileage as a varialbe ({answerid3:4, text=Corolla, mileage=38}. but also if i traverse up the tree give an average mile for the branch. Like say at branch Toyota, Gas, Compact the mileage would be avg(Camry, Corolla)

    输出有点偏,我正在寻找类似的东西。如果没有孩子那么没有孩子arraylist,并且attrbutes是一个对象的一部分(hashmap)

    the output is a little off, i am looking for something like this. if no children then no children arraylist, and attrbutes are part of one object (hashmap)

    {"data":[{"id":1,"children":
        [{"id": 2,"children":
            [{"id": 3 ,"children":
                [{"id": 4,"name":"Prius"}],"name":"Compact"}],"name":"Hybrid"},
        {"id":5,"children":
            [{"id":3,"children":
                [{"id":7,"MPG":38, "name":"Corolla"},
                 {"id":8,"MPG":28,"name":"Camry"}],"name":"Compact"}],"name":"Gas"}],"name":"Toyota"},
    {"id":9, "children":
        [{"id":10,"children":
            [{"id":3 ,"children":
                [{"id":11 ,"name":"Civic"}],"name":"Compact"}],"name":"Gas"}],"name":"Honda"}]}
    


    推荐答案

    您应该在所需的结构中创建用于建模数据的类。您基本上希望从某些基于行的数据构建层次结构,这非常类似于XML文档,这可能是一个合适的解决方案。但是你让我迷上了,所以我玩了之前我所拥有的并想出了这个:

    You should create classes to model your data, in the structure you require. You are basically wanting to build a hierarchical structure from some row based data, this is quite like an XML document, which might be an appropriate solution. But you got me hooked so I played about with what I had before and came up with this:

    public class Test { 
    
        public static void main(String[] args) 
        {
            // hierarchical data in a flattened list
            String[][] data = {
                    {"Toyota", "Gas", "Compact", "Corolla"},
                    {"Toyota", "Gas", "Compact", "Camry"},
                    {"Toyota", "Hybrid", "Compact", "Prius"},
                    {"Honda", "Gas", "Compact", "Civic"}
            };
    
            TreeManager treeManager = new TreeManager();
    
            for(String[] row : data)
            {
                // build the path to our items in the tree
                List<String> path = new ArrayList<String>();
                for(String item : row)
                {
                    // add this item to our path
                    path.add(item);
                    // will add it unless an Item with this name already exists at this path
                    treeManager.addData(treeManager, path);
                }
            }
    
            treeManager.getData(data[0]).putValue("MPG", 38);
            treeManager.getData(data[1]).putValue("MPG", 28);
    
            Gson gson = new Gson();
    
            System.out.println(gson.toJson(treeManager));
        }
    
        /**
         * This base class provides the hierarchical property of
         * an object that contains a Map of child objects of the same type.
         * It also has a field - Name
         *
         */
        public static abstract class TreeItem implements Iterable<TreeItem>{
    
            private Map<String, TreeItem> children;     
            private String name;
    
            public TreeItem() {
                children = new HashMap<String, TreeItem>();
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public void addChild(String key, TreeItem data) 
            {           
                children.put(key, data);
            }
    
            public TreeItem getChild(String key) 
            {           
                return children.get(key);
            }
    
            public boolean hasChild(String key) 
            {           
                return children.containsKey(key);
            }
    
            @Override
            public Iterator<TreeItem> iterator() {          
                return children.values().iterator();
            }           
        }
    
        /**
         * This is our special case, root node. It is a TreeItem in itself
         * but contains methods for building and retrieving items from our tree
         *
         */
        public static class TreeManager extends TreeItem
        {       
            /**
             * Will add an Item to the tree at the specified path with the value
             * equal to the last item in the path, unless that Item already exists 
             */
            public void addData(List<String> path)
            {
                addData(this, path);
            }
    
            private void addData(TreeItem parent, List<String> path)
            {
                // if we're at the end of the path - create a node
                String data = path.get(0);
                if(path.size() == 1)
                {
                    // unless there is already a node with this name
                    if(!parent.hasChild(data))
                    {
                        Group group = new Group();
                        group.setName(data);
                        parent.addChild(data, group);
                    }
                }
                else
                {
                    // pass the tail of this path down to the next level in the hierarchy
                    addData(parent.getChild(data), path.subList(1, path.size()));
                }
            }
    
            public Group getData(String[] path)
            {
                return (Group) getData(this, Arrays.asList(path));
            }
    
            public Group getData(List<String> path)
            {
                return (Group) getData(this, path);
            }
    
            private TreeItem getData(TreeItem parent, List<String> path)
            {
                if(parent == null || path.size() == 0)
                {
                    throw new IllegalArgumentException("Invalid path specified in getData, remainder: " 
                            + Arrays.toString(path.toArray()));
                }
                String data = path.get(0);
                if(path.size() == 1)
                {
                    return parent.getChild(data);
                }
                else
                {
                    // pass the tail of this path down to the next level in the hierarchy
                    return getData(parent.getChild(data), path.subList(1, path.size()));
                }
            }
        }
    
        public static class Group extends TreeItem {
    
            private Map<String, Object> properties;
    
            public Object getValue(Object key) {
                return properties.get(key);
            }
    
            public Object putValue(String key, Object value) {
                return properties.put(key, value);
            }
    
            public Group () {
                super();
                properties = new HashMap<String, Object>();
            }       
        }
    }
    

    我认为这符合大多数你到目前为止提到的要求,虽然我把MPG值的平均值作为读者的练习(我只有这么多时间......)。这个解决方案非常通用 - 您可能需要更具体的子类来更好地描述您的数据模型(如制造商,类型,模型),因为您可以将更多有用的方法挂起来(比如计算子项中的字段平均值)对象)
    ,你不必将这些属性作为 Object 的集合来处理,但是你会得到更复杂的代码来初始化你的数据结构列表。注意 - 这不是生产就绪代码,我刚刚提供了它作为如何用Java建模数据的示例。

    I think this meets most of the requirements you've mentioned so far, although I left out the averaging of the MPG values as an exercise for the reader (I've only got so much time...). This solution is very generic - you may want more concrete sub-classes that better describe your data model (like Manufacturer, Type, Model), as you will then be able to hang more useful methods off them (like calculating averages of fields in child objects) , and you wouldn't have to deal with the properties as a collection of Objects, but you then get more complicated code initialising your data structure from the list. Note - this is not production ready code, I've just provided it as an example of how you might go about modelling your data in Java.

    如果您是新手不仅是Java,还有面向对象的编程,那么你应该阅读这个主题。我在这里写的代码并不完美,我已经可以看到它可以改进的方法了。学习编写高质量的面向对象的代码需要时间和练习。阅读设计模式 Code Smells

    If you are new to not only Java but Object Orientated Programming then you should read up on the subject. The code I have written here is not perfect, I can already see ways it could be improved. Learning to write good quality object orientated code takes time and practice. Read up on Design Patterns and Code Smells .

    这篇关于使用列表/表中的json创建树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆