层次结构数据转移

Hierarchy Data shift

在 运行 获得 employee/manager 家谱的递归函数之后 - 提出了进一步的要求以保留整体经理结构。

所以我会想象输入数组看起来像这样

[["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
    }
}

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

循环1:找到包装器数组中最长的数组。这将是从最低职位到大老板的完整路径。以此为尺。最长的数组可能不止一个,具体取决于您的要求。

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

顺便说一句,对于这个问题,List 是比数组更好的数据结构。

输入:

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

这是第一个循环 - 它似乎提供了正确的规则。我在这里写了 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

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

我们的想法是构建一个 'bosses' 查找 table,从我们找到的最长的叶到根路径构建。每当我们有一个老板在查找 table 时,我们确保他出现在与他出现在最长路径中相同的位置,必要时用空值填充。

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]));
    }
}