如何在Java中拼合字典数组?

时间:2019-01-22 18:36:40

标签: java algorithm data-structures

我正在解决以下问题,我需要拼凑成排的字典:

例如-以下是输入:

[
    {'a':
        {'b':
            {'c':
                {'d':'e'}
            }
        }
    }, 
    {'a':{'b':{'c':{'d':{'e':'f'}}}}},
    {'a':'b'}
]

输出将是:

[
    {'a_b_c_d':'e'}, 
    {'a_b_c_d_e':'f'},
    {'a':'b'}
]

下面是我能想到的。有没有更好的方法来解决这个问题?

private static List<Map<String, String>> flatDictionary(final List<Map<String, Object>> input) {
    List<Map<String, String>> listHolder = new ArrayList<>();
    if(input == null || input.isEmpty()) {
        return listHolder;
    }
    for(Map<String, Object> mapHolder : input) {
        Map<String, String> m = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        Map<String, String> output = helper(mapHolder, sb, m);
        listHolder.add(output);
    }

    return listHolder;
}

private static Map<String, String> helper(final Map<String, Object> map, final StringBuilder sb, final Map<String, String> output) {
    String mapValue = null;
    for(Map.Entry<String, Object> holder : map.entrySet()) {
        String key = holder.getKey();
        Object value = holder.getValue();
        if(value instanceof Map) {
            sb.append(key).append("_");
            helper((HashMap<String, Object>) value, sb, output);
        } else if(value instanceof String) {
            sb.append(key);
            mapValue = (String) value;
        }
        output.put(sb.toString(), mapValue);
    }
    return output;
}

1 个答案:

答案 0 :(得分:1)

我会使用递归。

首先定义一种扁平化单个.meta-data

的方法
Map

注意:这不会尝试处理重复的密钥。

用法:

public static void flatten(final String keyPrefix, final Map<String, Object> input, final Map<String, Object> output) {
    for (final Map.Entry<String, Object> e : input.entrySet()) {
        final var key = keyPrefix.isBlank() ? e.getKey() : keyPrefix + "_" + e.getKey();
        if (e.getValue() instanceof Map) {
            // if the nested Map is of the wrong type bad things may happen
            flatten(key, (Map<String, Object>) e.getValue(), output);
        } else {
            output.put(key, e.getValue());
        }
    }
}

输出:

public static void main(final String[] args) throws InterruptedException {

    final var data = Map.of(
            "A", Map.of("a", "Expect A_a"),
            "B", Map.of("b1", Map.of(
                    "bb1", "expect B_b1_bb1",
                    "bb2", "expect B_b1_bb2"
            )),
            "C", "Expect C");

    final var output = new HashMap<String, Object>();

    flatten("", data, output);

    output.forEach((k, v) -> System.out.printf("%s -> %s%n", k, v));
}

现在,只需定义一个循环获取您的C -> Expect C A_a -> Expect A_a B_b1_bb2 -> expect B_b1_bb2 B_b1_bb1 -> expect B_b1_bb1

的方法
List

注意:这不会尝试处理重复的密钥。