0

childrenノードの子がそのプロパティに配列として格納されるツリー構造を使用する js アプリケーションがあります。データは MySQL DB から読み取られ、ツリー構造は php バックエンドで構築されます。次に、すべてが JSON として送信されます。

[
    {
        id: 1,
        children: [
            {
                id: 11
            },
            {
                id: 12
            }
        ]
    },
    {
        id: 2
    },
    {
        id: 3
    }
]

これは私が使用しているPHPスクリプトです。4 つのフェーズに分けることができます。

  • 最初に、ID によってノードの連想配列を作成します
  • 次に、最初のレベルのノードのみを取得する別の配列を作成します (parentId を定義せずに)
  • 次に、ID と parentId をチェックする最初の配列を再帰的に反復し、ツリーを構築します。
  • 最後に、出力連想配列をインデックス付き配列に書き換えます

これはソース全体です:

q = 'SELECT * FROM tasks';
$r = mysql_query($q);
$tasks = array();

//1.
while ($e = mysql_fetch_assoc($r)){
    $tasks[$e['Id']] = $e;
}

$sortedArray = array();

//2. get first level with no parent
foreach($tasks as $k => $v){
    if($v['parentId'] == 'null'){
        $sortedArray[$k] = $v;
        unset($tasks[$k]);
    }
}

//3. calls findChildren for first level nodes
function getChildren(array & $a1, array & $a2){
    foreach($a1 as $k => $v){
        findChildren($v, $a2, $k);      
    }
}

//recursive method checking if record's parent is already in the `sortedArray`.
//if yes, it's added to parent's `children` array. Otherwise it tries to
//find the parent in the node`s `children` array
function findChildren($rec1, array & $a2, $key){

    foreach($a2 as $k => $v){
        if($rec1['parentId'] == $v['Id']){
            $a2[$k]['children'][$rec1['Id']] = $rec1;
            unset($tasks[$key]);
        } else {
            if (isset($v['children'])){
                findChildren($rec1, $a2[$k]['children'], $key);
            }
        }
    }
}

//4. after `findChildren` `sortedArray` is an associative array, which
//is not valid for JSON
function makeIndexed(array & $arr, array & $par = null){
    if(is_null($par)){
        $arr = array_values($arr);
    } else {
        $par['children'] = array_values($arr);
    }

    for($i=0; $i<count($arr); $i++) {   
        $temp = @$arr[$i]['children'];
        if(isset($temp)) {
            makeIndexed($arr[$i]['children'], $arr[$i]);
        }       
    }
}

getChildren($tasks, $sortedArray);

makeIndexed($sortedArray);

echo json_encode($sortedArray);

今の私の目標は、Java バックエンドでこの動作を再現することです。現在、Hibernate クエリからのすべてのイベントを含むフラット リスト構造を取得しています。

public static Map<String,Object> getEvents() {

    DetachedCriteria criteria = DetachedCriteria.forClass(Event.class);

    return mapOk(hibernateTemplate.findByCriteria(criteria));
}

public static Map<String,Object> mapOK(List<Event> events){

    Map<String,Object> modelMap = new HashMap<String,Object>(2);
    modelMap.put("data", events);
    modelMap.put("success", true);

    return modelMap;
}

これに取り組む方法は?Java を最後に使用してからしばらく経ちましたが、Web プログラミングに Java を使用したことがないため、どこから始めて、どのようなアプローチをとるべきかがよくわかりません。多分これはどういうわけか自動化できますか?

4

1 に答える 1

1

なぜ誰かが私の質問を-1にしたのかわかりませんが、これが私が思いついたものです:

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.*;

import org.com.model.Task;

@Component
public class ReturnTasks {

    private static JSONObject sortedByParentTasks = null;
    private static JSONArray tasksTree = null;
    private static JSONObject taskChildrenObject;

    /**
     * Generates JSON String to return in the modelAndView
     * @param events
     * @return
     * @throws JSONException 
     * @throws IOException 
     * @throws JsonMappingException 
     * @throws JsonGenerationException 
     */

    public static String mapOK(List<Task> events) throws JSONException, JsonGenerationException, JsonMappingException, IOException{
        tasksTree = null;
        tasksTree = new JSONArray();
        sortedByParentTasks = null;
        sortedByParentTasks = new JSONObject();
        tasksTree = makeTree(events);

        return tasksTree.toString();
    }

    private static JSONArray makeTree(List<Task> list) throws JSONException, JsonGenerationException, JsonMappingException, IOException{

        Iterator<Task> listIterator = list.iterator();
        String parentId;

        while(listIterator.hasNext()){
            Task task = listIterator.next();
            JSONArray equalParentId;
            parentId = ""+task.getParentId();
            String json = new ObjectMapper().writeValueAsString(task);
            JSONObject taskJSON = new JSONObject(json);

            if (sortedByParentTasks.has(parentId)){
                sortedByParentTasks.accumulate(parentId, taskJSON);
            } else {
                equalParentId = new JSONArray();
                equalParentId.put(taskJSON);
                sortedByParentTasks.put(parentId, equalParentId);
            }
        }

        addNodes(sortedByParentTasks.getJSONArray("null"));

        return tasksTree;
    }

    private static void addNodes(JSONArray nodes) throws JSONException{
        for(int i=0, l=nodes.length(); i<l; i++){
            taskChildrenObject = nodes.getJSONObject(i);
            listHierarchy(taskChildrenObject);
            tasksTree.put(taskChildrenObject);
        }
    }

    private static void listHierarchy(JSONObject task) throws JSONException{
        JSONArray childrenArray = new JSONArray();
        JSONArray childNodes = new JSONArray();

        try {
            childNodes = sortedByParentTasks.getJSONArray(""+task.get("Id"));
        }catch(JSONException e){} 

        if (childNodes.length() > 0){
            for (int i=0, l=childNodes.length(); i<l; i++) {
                JSONObject childObject = childNodes.getJSONObject(i);
                childrenArray.put(childObject);
                try{
                    task.put("children", childrenArray);
                    task.put("leaf", false);
                }catch(JSONException e){}

                listHierarchy(childObject);
            }           
        }
    }

    /**
     * Generates modelMap to return in the modelAndView in case
     * of exception
     * @param msg message
     * @return
     */
    public static String mapError(String msg){

        Map<String,Object> modelMap = new HashMap<String,Object>(2);
        modelMap.put("message", msg);
        modelMap.put("success", false);

        return modelMap.toString();
    } 
}
于 2012-12-19T01:17:40.000 に答える