如何在Java中拼合字典数组

如何在Java中拼合字典数组

我正在处理下面的问题,我需要将一系列的命令放平:
例如-下面是一个输入:

[
    {'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;
}

最佳答案

我会用递归。
首先定义一种方法来展平单个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
public static final Map<String, Object> flattenAll(final List<Map<String, Object>> input) {
    final var output = new HashMap<String, Object>();
    input.forEach(map -> flatten("", map, output));
    return output;
}

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

关于java - 如何在Java中拼合字典数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54314503/

10-10 23:21