测试案例1:
输入
[{"key1": {"valueA": "", "valueB": ""}},
{"key2": {"valueC": "key3"}},
{"key3": {"valueD": "", "valueE": ""}}]
输出
[{"key1": {"valueA": "", "valueB": ""}},
{"key2": {"valueC": {"valueD": "", "valueE": ""}}]
测试案例2:
输入
[{"key1": {"valueA": "key2"}},
{"key2": {"valueB": "key3"}},
{"key3": {"valueC": "", "valueD": ""}}]
输出
[{"key1": {"valueA": {"valueB": {"valueC": "", "valueD": ""}}}}]
约束
所有值都应该是空字符串或对象。
深度 1 json 对象(
{"key1": ...}
, {"key2": ...}
, ...) 应该只有一个键值元素。
任务可以递归执行,这意味着遍历不应该限制在某个级别。
我在这个问题上纠结了一个星期...请帮我解决或命名java库,以便我看一下源代码。
这里有一个算法和一个实现。
objectMap
.rootKeys
中的键填充objectMap
。这些将是生成的地图中的顶级键。objectMap
映射,替换非空字符串值(例如,在"valueC": key3"
中,"key3"
被替换)。如果更换了钥匙,请将其从 rootKeys
.rootKeys
(具有相应的值)。import com.google.gson.Gson;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
class RecursiveJsonFlattener {
private final Map<String, Map<String, Object>> objectMap = new HashMap<>();
private final Set<String> rootKeys = new HashSet<>();
private final Object[] jsonData;
private final Gson serializer = new Gson();
public RecursiveJsonFlattener(String jsonData) {
this.jsonData = serializer.fromJson(jsonData, Object[].class);
}
public String getFlattened() {
for (var obj : jsonData) {
if (obj instanceof Map) {
addToKeys((Map<String, Object>) obj);
}
}
rootKeys.addAll(objectMap.keySet());
for (var map : objectMap.values()) {
substituteStringValues(map);
}
var resultingMap = rootKeys.stream().collect(Collectors.toMap(key -> key, objectMap::get));
return serializer.toJson(resultingMap);
}
private void addToKeys(Map<String, Object> map) {
for (var entry : map.entrySet()) {
if (!(entry.getValue() instanceof String)) {
objectMap.put(entry.getKey(), (Map<String, Object>) entry.getValue());
addToKeys((Map<String, Object>) entry.getValue());
}
}
}
private void substituteStringValues(Map<String, Object> map) {
for (var entry : map.entrySet()) {
var value = entry.getValue();
if (value instanceof String && !value.equals("")) {
map.put(entry.getKey(), objectMap.get(value));
rootKeys.remove(value);
} else if (entry.getValue() instanceof Map) {
substituteStringValues((Map<String, Object>) value);
}
}
}
}
用法:
public class Main {
public static void main(String[] args) {
String jsonString = "[{\"key1\": {\"valueA\": \"\", \"valueB\": \"\"}},\n" +
"{\"key2\": {\"valueC\": \"key3\"}},\n" +
"{\"key3\": {\"valueD\": \"\", \"valueE\": \"\"}}]";
System.out.println(new RecursiveJsonFlattener(jsonString).getFlattened());
// prints {"key1":{"valueA":"","valueB":""},"key2":{"valueC":{"valueD":"","valueE":""}}}
}
}