I'm building a small micro service to implement a couple of sorting algorithms using Java & Vert.x
One of my requirements is to handle nested lists like [5, [4, 3, 2], 1, [[0]]]
The request body is a JSON object like:
{"arr": [5, [4, 3, 2], 1, [[0]]]}
How can I parse a JSON object/ JSON array with a nested list to a flat list in Java?
// This is how I handle simple lists
private void doBubbleSort(RoutingContext routingContext) {
JsonObject json = routingContext.getBodyAsJson();
JsonArray jsonArray = json.getJsonArray("arr");
// How do I get the size of the list if it is multi-dimensional
int size = jsonArray.size();
int[] unsortedList = new int[size];
for (int i = 0; i < size; i++) {
// Here I want to check whether the current item is an int or
// another nested list. if it is a list, i want to loop over it
// and also add it to the result
unsortedList[i] = jsonArray.getInteger(i);
}
...
}
The result I'm looking for:
int[5, 4, 3, 2, 1, 0]
I know I need to check whether the current value is of type int or list, but struggling to get it working with the type conversions from JSON to int to list.
In Python I can do this without the type conversions.
def flatten_list(arr: list):
nested_arr = deepcopy(arr)
while nested_arr:
sublist = nested_arr.pop(0)
if isinstance(sublist, int):
yield sublist
if isinstance(sublist, list):
nested_arr = sublist + nested_arr
-
Are you using Java8+ or Java7- ? The second question is how deep the nest can be?aBnormaLz– aBnormaLz2019年01月02日 15:35:09 +00:00Commented Jan 2, 2019 at 15:35
-
@aBnormaLz I'm using Java8. thankskrankit– krankit2019年01月02日 16:28:16 +00:00Commented Jan 2, 2019 at 16:28
-
Okay, and how deep the nest can be? only 3 levels? More?aBnormaLz– aBnormaLz2019年01月02日 16:32:38 +00:00Commented Jan 2, 2019 at 16:32
-
@aBnormaLz More than 3. I'm expecting lists of different complexity. Some may be simple [3, 2, 1] and some could have nested elements like [1, [[[[3]]]], 2] or [[1], 2, 3]. But the complexity is not known in advancekrankit– krankit2019年01月02日 16:54:23 +00:00Commented Jan 2, 2019 at 16:54
1 Answer 1
According to your answers try the following:
private void doBubbleSort(RoutingContext routingContext) {
JsonObject json = routingContext.getBodyAsJson();
JsonArray jsonArray = json.getJsonArray("arr");
List<?> list = jsonArray.getList();
List<Integer> flatList = list.stream()
.map(this::getOrFlatten)
.flatMap(List::stream)
.collect(Collectors.toList());
// convert List<Integer> to int[]
// ...
}
private List<Integer> getOrFlatten(Object o) {
if(o instanceof Integer) {
return Collections.singletonList((Integer) o);
} else if(o instanceof List) {
List<?> list = (List) o;
return list.stream()
.map(this::getOrFlatten)
.flatMap(List::stream)
.collect(Collectors.toList());
} else {
throw new IllegalArgumentException(o.getClass() + " is not supported at getOrFlatten");
}
}
2 Comments
List<?> list = jsonArray.getList(); was exactly what I needed. Will need to dig deeper into java genericslist.parallelStream(), if you want to run the multiple getOrFlatten calls concurrently.