获取JSON中可变深度的ID列表

huangapple go评论65阅读模式
英文:

Java - Get list of id's from JSON with a variable depth

问题

我试图构建多个子树的id列表,例如我需要:\n- 1, 3, 6\n- 1, 4\n- 1, 5\n- 2, 7, 8, 9\n- 2, 7, 10, 11\n\n我之前开发了一个遍历整个树的例程(递归),使用了jackson库的功能和对象,不知道我是否可以将其适应到这个用例。\n\n有没有一种方法来构建这些列表并修改我的例程来实现它或者其他方法(另一个例程,...)\n\n谢谢

英文:

I have a JSON file with a fluctuating depth and each node (different depth). So it's built like a General tree :

获取JSON中可变深度的ID列表

And here is a sample json (not the real one but a mock file but the structure remains the same) :

{
  "arbre" : {
    "children" : [
      {
        "id" : 1,
        "children" : [
          {
            "id" : 3,
            "children" : [
              {
                "id" : 6,
                "children" : []
              }
            ]
          },
          {
            "id" : 4,
            "children": []
          },
          {
            "id" : 5,
            "children": []
          }
        ]
      },
      {
        "id" : 2,
        "children" : [
          {
            "id" : 7,
            "children" : 
            [
              {
                "id" : 8,
                "children" : [
                  {
                    "id" : 9,
                    "children" : []
                  }
                ]
              },
              {
                "id" : 10,
                "children" : [
                  {
                    "id" : 11,
                    "children" : []
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

I'm trying to build multiple list of id for each subtrees, so for exemple I need :

  • 1, 3, 6
  • 1, 4
  • 1, 5
  • 2, 7, 8, 9
  • 2, 7, 10, 11

I previously developped a routine that traverse the entire tree (recursive) using jackson and don't know if I can adapt it to this use case.

Here it is :

/**
     * getJSONNode: not return value, recursive function that will browse (uses functionalities and objects of the com.fasterxml.jackson library)
     * 
     * 
     * {talendTypes} String, JsonNode
     * 
     * {Category} User Defined
     * 
     * {param} JsonNode(jNode) input: the function will check if the node is an array of object and will process and keep iterate until it reaches the bottom of the tree
     * {param} string(filepath) input: The string is a path to a directory where the temp files will be stored
     * 
     * {example} getJSONNode(jNode, "/test/") # Files will be generated in the directory /test/
     */
    public static void getJSONNode(JsonNode jNode, String filepath) throws IOException {
    	//System.out.println("Get Node");
    	JsonNode tempNoded = jNode.get("children");
    	if(tempNoded.isArray()) {
    		for(int i = 0; i < tempNoded.size(); i++) {
    			System.out.println("Name : " + tempNoded.get(i).get("name"));
    			System.out.println("Title : " + tempNoded.get(i).get("title"));
    			System.out.println("Title : " + tempNoded.get(i).get("id"));
    			System.out.println("================== Writing file ===================");
    			String id = tempNoded.get(i).get("id").toString();
    			String name = tempNoded.get(i).get("name").toString();
    			String title = tempNoded.get(i).get("title").toString();
    			String color = tempNoded.get(i).get("color").toString();
    			String order = tempNoded.get(i).get("order").toString();
    			String parentId = tempNoded.get(i).get("parentId").toString();
    			String persons = tempNoded.get(i).get("persons").toString();
    			String profils = tempNoded.get(i).get("profils").toString();
    			String paramNoeud = tempNoded.get(i).get("paramNoeud").toString();
    			String description = tempNoded.get(i).get("description").toString();
    			// disable not present in all dimensions so not usable
    			//String disabled = tempNoded.get(i).get("disabled").toString();
    			String oldId = tempNoded.get(i).get("oldId").toString();
    			
    			String str = id + ";" + name + ";" + title + ";" + color + ";" + order + ";" + parentId + ";" + persons + ";" + profils + ";" + paramNoeud + ";" + description + ";" + oldId;
    			byte[] strToBytes = str.getBytes();
    			
    			String filename = (name + "_" + order + ".csv").replaceAll("\"", "");
    			
    			File file = new File(filepath + filename);
    			file.getParentFile().mkdirs();
    			file.createNewFile();    			
    			FileOutputStream outputStream = new FileOutputStream(filepath + filename);
    			
    			outputStream.write(strToBytes);
    			outputStream.close();
    			
    			getJSONNode(tempNoded.get(i), filepath);
    		}
    		
    	}
    }

So is there a method to build those lists and modify my routine to do it or something else (another routine, ...)

Thanks

答案1

得分: 1

我建议使用递归解决方案,跟踪当前子树:

publi List<List<String>> getSubtrees(JsonNode childrenNode, List<String> currentSubtree) {
    ArrayList<List<String>> subtrees = new ArrayList<>();

    if (childrenNode.isEmpty()) {
        subtrees.add(currentSubtree);
    } else {
        for (JsonNode node : childrenNode) {
            String id = node.get("id").asText();
            JsonNode children = node.get("children");
            List<String> childSubtree = new ArrayList<>(currentSubtree);
            childSubtree.add(id);

            subtrees.addAll(getSubtrees(children, childSubtree));
        }
    }

    return subtrees;
}

调用方式:

List<List<String>> subtrees = getSubtrees(children, List.of());

其中children是顶级子节点的数组节点,在你的情况下是一个arbre -> children的JSON节点。这只是一个示例,请注意类型/空检查。

英文:

I would suggest a recursive solution that keeps track of current subtree:

publi List&lt;List&lt;String&gt;&gt; getSubtrees(JsonNode childrenNode, List&lt;String&gt; currentSubtree) {
    ArrayList&lt;List&lt;String&gt;&gt; subtrees = new ArrayList&lt;&gt;();

    if (childrenNode.isEmpty()) {
        subtrees.add(currentSubtree);
    } else {
        for (JsonNode node : childrenNode) {
            String id = node.get(&quot;id&quot;).asText();
            JsonNode children = node.get(&quot;children&quot;);
            List&lt;String&gt; childSubtree = new ArrayList&lt;&gt;(currentSubtree);
            childSubtree.add(id);

            subtrees.addAll(getSubtrees(children, childSubtree));
        }
    }

    return subtrees;
}

call it as

List&lt;List&lt;String&gt;&gt; subtrees = getSubtrees(children, List.of());

where children is an array node of top level children, in your case it's a arbre -&gt; children json node. That's an example, pay attention to type/null checks.

答案2

得分: 1

以下是您提供的代码的中文翻译部分:

public List<List<String>> getSubtrees(JsonNode childrenNode, List<String> currentSubtree) {
    ArrayList<List<String>> subtrees = new ArrayList<>();

    if (childrenNode.size() == 0) {
        subtrees.add(currentSubtree);
    } else {
        for (int i = 0; i < childrenNode.size(); i++) {
            //System.out.println(childrenNode.get(i).toString());
            String id = childrenNode.get(i).get("id").toString();
            //System.out.println(id);
            JsonNode children = childrenNode.get(i).get("children");
            List<String> childSubtree = new ArrayList<>(currentSubtree);
            childSubtree.add(id);
            //System.out.println(childSubtree.toString());
            subtrees.addAll(getSubtrees(children, childSubtree));
        }
    }
    //System.out.println(subtrees.size());
    return subtrees;
}

public List<List<String>> preProcessGetSubtrees(String tree) throws JsonProcessingException, IOException {
    if (!isNullorEmpty(tree)) {
        List<String> currentSubtree = new ArrayList<>();
        ObjectMapper objMapper = new ObjectMapper();
        System.out.println("=========================== PLANETE TREE PROCESSING ========================");
        List<List<String>> subtrees = getSubtrees(objMapper.readTree(tree).get("arbre").get("children"), currentSubtree);
        System.out.println("=========================== PLANETE TREE PROCESSED ========================");
        return subtrees;
    } else {
        System.out.println("============================================================================");
        System.out.println("==================== WARNING THE TREE IS NOT VALID =========================");
        System.out.println("============================================================================");
        return null;
    }
}

请注意,代码中的HTML实体编码已被还原为正常的字符。如果需要进一步的帮助,请随时提问。

英文:

With the solution in the (accpeted) answer (https://stackoverflow.com/a/76456855/14707253)

I made a few modifications but the solution in itself worked so here is the final code : Function

public List&lt;List&lt;String&gt;&gt; getSubtrees(JsonNode childrenNode, List&lt;String&gt; currentSubtree) {
ArrayList&lt;List&lt;String&gt;&gt; subtrees = new ArrayList&lt;&gt;();
if (childrenNode.size() == 0) {
subtrees.add(currentSubtree);
} else {
for (int i = 0; i &lt; childrenNode.size(); i++) {
//System.out.println(childrenNode.get(i).toString());
String id = childrenNode.get(i).get(&quot;id&quot;).toString();
//System.out.println(id);
JsonNode children = childrenNode.get(i).get(&quot;children&quot;);
List&lt;String&gt; childSubtree = new ArrayList&lt;&gt;(currentSubtree);
childSubtree.add(id);
//System.out.println(childSubtree.toString());
subtrees.addAll(getSubtrees(children, childSubtree));
}
}
//System.out.println(subtrees.size());
return subtrees;
} 

And the call of the function :

public List&lt;List&lt;String&gt;&gt; preProcessGetSubtrees(String tree) throws JsonProcessingException, IOException {
if(!isNullorEmpty(tree)) {
List&lt;String&gt; currentSubtree = new ArrayList&lt;&gt;();
ObjectMapper objMapper = new ObjectMapper();
System.out.println(&quot;=========================== PLANETE TREE PROCESSING ========================&quot;);
//List&lt;List&lt;String&gt;&gt; subtrees = 
List&lt;List&lt;String&gt;&gt; subtrees = getSubtrees(objMapper.readTree(tree).get(&quot;arbre&quot;).get(&quot;children&quot;), currentSubtree);
System.out.println(&quot;=========================== PLANETE TREE PROCESSED ========================&quot;);
return subtrees;
} else {
System.out.println(&quot;============================================================================&quot;);
System.out.println(&quot;==================== WARNING THE TREE IS NOT VALID =========================&quot;);
System.out.println(&quot;============================================================================&quot;);
return null;
}

huangapple
  • 本文由 发表于 2023年6月12日 17:54:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定