Разбор многомерного массива JSON в плоский список int в Java - PullRequest
0 голосов
/ 02 января 2019

Я создаю небольшой микро-сервис для реализации нескольких алгоритмов сортировки с использованием Java & Vert.x

Одним из моих требований является обработка вложенных списков, таких как [5, [4, 3, 2], 1, [[0]]]

Тело запроса является объектом JSON, например:

{"arr": [5, [4, 3, 2], 1, [[0]]]}

Как можно проанализировать объект JSON / массив JSON с вложенным списком в плоский список в 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);
    }

    ...
}

Результат, который я ищу:

int[5, 4, 3, 2, 1, 0]

Я знаю, что мне нужно проверить, имеет ли текущее значение тип int или list, но изо всех сил пытается заставить его работать с преобразованиями типов из JSON в int в список.

В Python я могу сделать это без преобразования типов.

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

1 Ответ

0 голосов
/ 02 января 2019

В соответствии с вашими ответами попробуйте следующее:

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

Здесь вы можете найти, как конвертировать List в int []

...