简体   繁体   English

如何在 Java 中展平一系列字典?

[英]How to flatten an array of dictionaries in Java?

I am working on below problem where I need to flatten array of dicts:我正在解决以下问题,我需要将 dicts 数组展平:

For example- Below is an input:例如 - 下面是一个输入:

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

And the output will be:输出将是:

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

Below is what I was able to come up with.以下是我能想出的。 Is there any better way to solve this problem?有没有更好的方法来解决这个问题?

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

I would use recursion.我会使用递归。

First define a method to flatten a single Map首先定义一个方法来展平单个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());
        }
    }
}

NB: This makes no attempt to deal with duplicate keys.注意:这不会尝试处理重复的键。

Usage:用法:

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

Output:输出:

C -> Expect C
A_a -> Expect A_a
B_b1_bb2 -> expect B_b1_bb2
B_b1_bb1 -> expect B_b1_bb1

Now, simply define a method that loops to take your List现在,只需定义一个循环获取您的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;
}

NB: This makes no attempt to deal with duplicate keys.注意:这不会尝试处理重复的键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM