0

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
4
  • Are you using Java8+ or Java7- ? The second question is how deep the nest can be? Commented Jan 2, 2019 at 15:35
  • @aBnormaLz I'm using Java8. thanks Commented Jan 2, 2019 at 16:28
  • Okay, and how deep the nest can be? only 3 levels? More? Commented 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 advance Commented Jan 2, 2019 at 16:54

1 Answer 1

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

Here you can find how to convert List to int []

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Had no idea how to handle the 'unknown' values. The List<?> list = jsonArray.getList(); was exactly what I needed. Will need to dig deeper into java generics
Your welcome :) also you can take a look at list.parallelStream(), if you want to run the multiple getOrFlatten calls concurrently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.