'Get parent from nested Map - Java
I have this json Input
[
{
"id": "32",
"name": "Menu full"
"description": "Here is the object {id} is {name}"
},
{
"id": "60",
"name": "Side bar menu"
"description": "Here is the object {id}",
"children": [
{
"id": "60.1",
"name": ""
"description": "Here is the object {id} is {name}",
"children": []
}
]
}
]
Here is the java class representation.
public class Menu {
String id;
String name;
String description;
List <Menu> children;
//Getters and Setters
}
This is a recursive java object since the children is the same type as the parent.
I need to search and replace all variables inside "{}" with the value of the search by key using the value obtained from the string in {}. from the given json this should be the output.
Output
[
{
"id": "32",
"name": "Menu full"
"description": "Here is the object 32 is Menu full"
},
{
"id": "60",
"name": "Side bar menu"
"description": "Here is the object 60",
"children": [
{
"id": "60.1",
"name": ""
"description": "Here is the object 60.1 is Side bar menu",
"children": []
}
]
}
]
As you can see in the children there was no "{name}" in the current object to replace for. In that case the logic should get the "name" value from the key "name" obtained from the parent. If the parent dont have that value in the key (null) or is empty then the replace for the children should be String.empty
In order to achieve this I transformed the java object to a Map<String, Object> since I need to first determinate if the value has a replacement String ("{value}") and then search the key based on that replacement String.
Assuming I have already transformed the object to a Map.
private void ReplaceAllVariablesMap (Map<String, Object> objectMap) {
objectMap.entrySet()
.forEach(entry -> {
String value = Optional.ofNullable(entry.getValue()).orElse("").toString();
List<String> valuesToReplace = getValuesToReplace(value);
if(entry.getValue() instanceof String && valuesToReplace.size() > 0){
valuesToReplace.forEach(v -> {
String valueToReplaceWith = getValueByKey(objectMap, getValueFromBracketString(v));
value.replace(v, valueToReplaceWith);
});
}
if (entry.getValue() instanceof Map) {
Map<String, Object> map = (Map<String, Object>) entry.getValue();
ReplaceAllVariablesMap(map);
} else if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
list.forEach(listEntry -> {
if (listEntry instanceof Map) {
Map<String, Object> map = (Map<String, Object>) listEntry;
ReplaceAllVariablesMap(map);
}
});
}
});
}
private List<String> getValuesToReplace(String value){
return Pattern.compile("\\{(.*?)\\}")
.matcher(value)
.results()
.map(MatchResult::group)
.collect(Collectors.toList());
}
private String getValueByKey (Map<String, Object> objectMap, String value) {
String foundValue = null;
for (var entry : objectMap.entrySet()){
if(entry.getValue() instanceof String && entry.getKey().equalsIgnoreCase(value)){
foundValue = entry.getValue().toString();
break;
}
if (entry.getValue() instanceof Map) {
Map<String, Object> map = (Map<String, Object>) entry.getValue();
getValueByKey(map, value);
} else if (entry.getValue() instanceof List) {
List<?> list = (List<?>) entry.getValue();
list.forEach(listEntry -> {
if (listEntry instanceof Map) {
Map<String, Object> map = (Map<String, Object>) listEntry;
getValueByKey(map, value);
}
});
}
}
return foundValue;
}
private String getValueFromBracketString(String bracketValue) {
return bracketValue.replaceAll("\\{(.*?)\\}", "$1");
}
I am really struggling on how to get the parent object. Also I have to iterate to whole Map first to locate the value with "{}" to replace and then to search for the key.
The concrete question is, How to get the parent object? and any approach on how to improve this logic.
Solution 1:[1]
I think you can add an argument for parent. That is...
private void ReplaceAllVariablesMap (Map<String, Object> objectMap, Map<String, Object> parent) {
And then you have to put parent when calling it.
ReplaceAllVariablesMap(map, lastEntry);
Otherwise, you need to add a member in "Menu" for "parent" so that you can get it.
public class Menu {
Menu parent;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nick |
