Создание дерева с использованием json из списка / таблицы

Допустим, в этом случае у меня есть таблица / список n = 3, но n может быть неограниченным.

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

и я хочу создать вывод json для родительского / дочернего дерева, например, с помощью Java. (Я использовал 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}
                        ]
                }

               ]      
        }

какой будет код / шаги для этого. Я просмотрел множество тегов, но в основном люди печатают выходные данные, а не рекурсивно собирают hashmap / ArrayList для GSON, чтобы проанализировать adn write для API. В другой точке каждый идентификатор имеет другие данные, связанные с ним, которые должны быть включены в вывод json. например, вместо {groupid: 1} потребуется этот {groupid: 1, text = toyota}.

любая помощь очень ценится, так как я довольно новичок в Java, поскольку я из SAS.

Я получаю такие данные (просто матрицу списка) Toyota, Gas, Compact, Corolla

Toyota, Газ, Компакт, CamryToyota, Гибрид, Компакт, ПриусHonda, Газ, Компакт, Civic

При необходимости я могу РЕФОРМИРОВАТЬ ДАННЫЕ в две таблицы

parentId parText answerId

1 Тойота 1 1 Тойота 2 1 Тойота 3 2 Honda 4

answerId level answerTextid answerText

1 1 1 Газ 1 2 2 Compact 1 3 3 Corolla 2 1 1 Газ 2 2 2 Compact 2 3 4 Camry…

Затем мне нужно сделать это деревом (вложенный вывод, как показано в JSON с parent / children - точно так же, как если бы вы создавали каталог файловой системы)

Еще одно, что я хотел бы сделать, - это то, что для каждого автомобиля пробег варьируется ({answerid3: 4, text = Corolla, m miles = 38}. Но также, если я прохожу по дереву, получаю среднюю милю за ветку. скажем в филиале Тойота, Газ, Компакт, пробег будет средним (Camry, Corolla)

выход немного выключен, я ищу что-то вроде этого. если нет дочерних, то нет дочерних массивов, и атрибуты являются частью одного объекта (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"}]}

Ответы на вопрос(1)

Решение Вопроса

труктуре. По сути, вы хотите построить иерархическую структуру из некоторых данных на основе строк, это очень похоже на XML-документ, который может быть подходящим решением. Но вы меня зацепили, поэтому я поиграл с тем, что у меня было раньше, и придумал это:

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 в качестве упражнения для читателя (у меня только так много времени ...). Это решение очень универсальное - вам могут потребоваться более конкретные подклассы, которые лучше описывают вашу модель данных (например, «Производитель», «Тип», «Модель»), поскольку тогда вы сможете свисать с них более полезные методы (например, вычисление средних значений для дочерних элементов). объекты), и вам не придется иметь дело со свойствами в виде коллекцииObjects, но вы получите более сложный код, инициализирующий структуру данных из списка. Обратите внимание - это не готовый к работе код, я просто предоставил его в качестве примера того, как вы можете приступить к моделированию ваших данных в Java.

Если вы новичок не только в Java, но и в Объектно-ориентированное программирование тогда вы должны прочитать эту тему. Код, который я написал здесь, не идеален, я уже вижу способы его улучшения. Обучение написанию качественного объектно-ориентированного кода требует времени и практики. Следить за публикациямиШаблоны проектировани а также Кодовые запахи .

 Malcolm Smith21 мая 2012 г., 22:57
Я обновил пример, чтобы показать вам, что я имею в виду под абстрактным суперклассом. Я думаю, что мне здесь не хватает понимания того, как поступают ваши данные и как они структурированы. Кажется, что вы вводите список групп, которые содержат список ответов (один уровень - просто список списков, но в выходном файле JSON есть группа с вложенными уровнями ответов в ответах, и я не совсем понимаю, как Если вы хотите получить более подробную информацию, обновите исходный вопрос.
 Bob Stein22 мая 2012 г., 21:07
я обновил некоторые подробности проблемы
 Bob Stein21 мая 2012 г., 17:18
В приведенном выше коде вы добавляете к каждому списку массивов ответов, но как перебрать начальный «список», чтобы получить желаемый результат? это то, как я это делал, когда уровни - это «уровни» каждой строки. HashMap map = new HashMap (); for (int i = 0; i <list.size (); i ++) {HashMap item = (HashMap) list.get (i); int levId = (Integer) item.get ("level"); for (int lev = 0; lev <levId; lev ++)
 Bob Stein21 мая 2012 г., 17:01
Я ценю помощь. но что вы подразумеваете под созданием абстрактного суперкласса, который предоставляет свойство (объект, у которого есть список ответов), и создаете свои объекты Group и Answer, расширяя его. для меня, я думаю, что это то, что я пытался сделать, но безрезультатно. я пытался использовать hashmaps и arraylist, чтобы создать один «большой» объект и заставить GSON разобрать его.
 Bob Stein23 мая 2012 г., 05:23
Большое спасибо за помощь по объектно-ориентированной ссылке. мой опыт в основном VB (VBA), SAS, SQL программирование. если вам когда-нибудь понадобится статистика / математика, SAS, SQkl, помогите мне, я буду рад вернуть услугу.

Ваш ответ на вопрос