层次结构数据移位

时间:2015-04-13 09:21:33

标签: java hierarchical-data

在运行递归函数以获取员工/经理家族树之后 - 进一步要求保留整体经理结构。

所以我认为输入数组看起来像这样

[["Employee A", "1000", "Employee B", "1001", "Employee C", "1002"],
["Employee D", "1003", "Employee C", "1002"]]

并且输出数组需要看起来像这样

[["Employee A", "1000", "Employee B", "1001", "Employee C", "1002"],
["Employee D", "1003", null, null, "Employee C", "1002"]]

需要以这种方式对层次结构进行排序,以表明员工C始终保留高级经理的角色

public void refactorArray(String jsonData) throws Exception {
    JSONArray array = new JSONArray(jsonData);
    for (int i = 0; i < array.length(); i++) {

        //flag previous position of grandfather manager and name/id

        // if previous position does not match current position - do logic to pop the array at that element to put it back into the previous position
    }
}

3 个答案:

答案 0 :(得分:1)

你可以在两个循环中完成,

Loop1:找到包装器数组中最长的数组。这将是从最低位置到大老板的完整路径。以此为统治者。根据您的要求,可能有多个最长的阵列。

Loop2:对于每个数组,将元素与我们找到的规则进行比较,当找到不匹配的元素时,添加一个null(或两个带ID的Null)元素。

顺便说一句,对于这个问题,List会比数组更好的Datastructure。

输入:

a-b-c-d-e-f
x-c-e
y-b-d-f

您找到a-b-c-d-e-f

的第一步

然后将x-c-e与第二个元素中的每个元素进行比较,得到x-null-c-null-e-null

答案 1 :(得分:1)

在首先找到最长的一个,并将其作为未来boss填充的参考的想法的基础上,产生以下代码,这适用于上述情况。

我们的想法是构建一个“老板”查找表,它是根据我们找到的最长的叶到根路径构建的。每当我们在查找表中有一个boss时,我们确保它出现在与最长路径中出现的位置相同的位置,并根据需要填充空值。

import org.json.JSONArray;
import java.util.ArrayList;
import java.util.HashMap;

public class T {
    static String refactor(String jsonData) {
        JSONArray array = new JSONArray(jsonData);

        // find longest array in original container
        JSONArray longest = null;
        for (int i=0; i<array.length(); i++) {
            JSONArray a = array.getJSONArray(i);
            if (longest == null || a.length() > longest.length()) {
                longest = a;
            }
        }

        // build a map with the people in "longest", for quick lookup
        HashMap<String, Integer> bosses = new HashMap<String, Integer>();
        for (int i=0; i<longest.length(); i+=2) {
            bosses.put(longest.getString(i) + "|" + longest.getString(i+1), i);
        }

        // prepare target container       
        ArrayList<JSONArray> container = new ArrayList<JSONArray>();

        // fill in missing values
        for (int i=0; i<array.length(); i++) {
            JSONArray a = array.getJSONArray(i);
            ArrayList<String> refactored = new ArrayList<String>();
            // copy leaf employee
            refactored.add(a.getString(0));
            refactored.add(a.getString(1));
            for (int j=2; j<a.length(); j+=2) {
                // possibly fill in nulls before adding this boss
                String boss = a.getString(j) + "|" + a.getString(j+1);
                if (bosses.containsKey(boss)) {
                    for (int k=j; k<bosses.get(boss); k++) {
                        // pad with nulls until we reach target position
                        refactored.add(null);
                    }
                }
                refactored.add(a.getString(j));
                refactored.add(a.getString(j+1));
            }
            container.add(new JSONArray(refactored));
        }
        return new JSONArray(container).toString();
    }

    public static void main(String args[]) {
        System.out.println(refactor(args[0]));
    }
}

答案 2 :(得分:0)

这是第一个循环 - 它似乎正确地提供了规则。我在这里写了javascript -

**************最新守则********************* 17/04/2015

http://jsfiddle.net/y74z42ms/25/

对于循环2 - 我是否循环遍历每个数组元素和规则 - 如果是,那么应用什么逻辑来插入空条目?

---这看起来是否正确?

var input = [
    ["AaronG", "RupertJ", "ScottK", "DannyC", "LennyD"],
    ["JackieP", "RupertJ", "ScottK", "DannyC", "LennyD"],
    ["NelsaI", "SamJ", "ScottK", "DannyC", "LennyD"],
    ["BrentD", "SamJ", "ScottK", "DannyC", "LennyD"],
    ["MaryS", "CardinalE", "DannyC", "LennyD"],
    ["GaroleP", "CardinalE", "DannyC","LennyD"],
    ["AlanA", "ChanA", "KopecK", "LennyD"],
    ["GerryA", "ChanA", "KopecK", "LennyD"],
    ["BurlS", "TodD", "KopecK", "LennyD"],
    ["KenS", "TodD", "KopecK", "LennyD"],
    ["JerryU", "JasonA", "JefferyW", "MargotS", "LennyD"],
    ["BakerI", "JasonA", "JefferyW", "MargotS", "LennyD"]
];
console.log("input", input);
$('#in').html(input.toString());

//:loop1
var ruleStorage = [];
var rule = null;
var lastRule = null;
for (i = 0; i < input.length; i++) {
    //count the nested array elements - store it if its the longest
    rule = input[i];
    if (lastRule != null) {
        if (lastRule.length > rule.length) {
            rule = lastRule;
        } 
            ruleStorage.push(rule);    
    }
    lastRule = rule;
}

ruleStorage = $.unique(ruleStorage); //provides unique rules
//:loop1


//:loop2
//use rule 1
console.log("ruleStorage", ruleStorage);
rule = ruleStorage[0];
var output = [];
for (i = 0; i < input.length; i++) {
    //count the nested array elements - store it if its the longest
    var nestedEl = input[i];
    var newNest = [];
    //compare nestedEl with rule - and use the rule to insert null spaces accordingly

    //create null entries first
    for (j = 0; j < rule.length; j++) {
        newNest[j] = null;
    }

    //loop through the rule and compare
    for (j = 0; j < rule.length; j++) {
        var originalPos = rule.indexOf(rule[j]);
        var currentPos = nestedEl.indexOf(rule[j]);

        //build the new nest
        //if its in the original postion restore it as such
        if (originalPos == currentPos) {
            newNest[j] = nestedEl[j];
        }

        //element is new and doesn't exist in the rule
        if (
        currentPos == -1 && originalPos != -1 && rule.indexOf(nestedEl[j]) == -1 && nestedEl[j] !== undefined) {
            newNest[originalPos] = nestedEl[j];
        }

        //element is not new but its in the wrong place
        if (
        rule.indexOf(nestedEl[j]) != -1 && nestedEl[j] !== undefined) {
            var rulePos = rule.indexOf(nestedEl[j]);
            newNest[rulePos] = nestedEl[j];
        }

    }
    //console.log("newNest", newNest);
    //console.log("nestedEl", nestedEl);

    output.push(newNest);

}
console.log("output", output);

$('#out').html(output.toString());
//:loop2