Majestic
Majestic

Reputation: 938

Retrieve value from List<Map> and insert it into another List<Map>

I need to change the format of a List < Map < String, Object>> to another format of List < Map < String, Object>>. I have this collection :

[{
    "OPERATION_NAME": "COPY",
    "OPERATION_STATUS": "READY",
    "COUNT(1)": 1
}, {
    "OPERATION_NAME": "ARCHIVE",
    "OPERATION_STATUS": "READY",
    "COUNT(1)": 1
}, {
    "OPERATION_NAME": "EXPORT_CA",
    "OPERATION_STATUS": "READY",
    "COUNT(1)": 1
}, {
    "OPERATION_NAME": "MERGE",
    "OPERATION_STATUS": "READY",
    "COUNT(1)": 1
}, {
    "OPERATION_NAME": "MERGE",
    "OPERATION_STATUS": "DONE",
    "COUNT(1)": 1
}]

And I change it to this :

[{
    "READY": 0,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "MERGE"
}, {
    "READY": 0,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "ARCHIVE"
}, {
    "READY": 0,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "COPY"
}, {
    "READY": 0,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "EXPORT_CA"
}]

But I can't manage to retrieve the COUNT(1)'s value and set it to the new object I'm creating.

At the end I should have this :

[{
    "READY": 1,
    "NEW": 0,
    "DONE": 1,
    "OPERATION_NAME": "MERGE"
}, {
    "READY": 1,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "ARCHIVE"
}, {
    "READY": 1,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "COPY"
}, {
    "READY": 1,
    "NEW": 0,
    "DONE": 0,
    "OPERATION_NAME": "EXPORT_CA"
}]

Here's my function to convert an object to antoher one :

private List<Map<String, Object>> transformObject(List<Map<String, Object>> resDB) {
        Gson gson = new Gson();
        LOGGER.info("Json response : {}", gson.toJson(resDB));

        List<Map<String, Object>> result = new ArrayList<>();

        List<String> listOfOperationName = new ArrayList<>();
        List<String> listOfOperationStatus = new ArrayList<>();

        // Retrieve OP Name and OP Status
        for (Map<String, Object> map : resDB) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if(key.equals("OPERATION_NAME")) {
                    listOfOperationName.add(value.toString());
                } else if(key.equals("OPERATION_STATUS")) {
                    listOfOperationStatus.add(value.toString());
                }
            }
        }

        // Remove duplicates
        Set<String> setName = new HashSet<>(listOfOperationName);
        listOfOperationName.clear();
        listOfOperationName.addAll(setName);
        // Remove duplicates
        Set<String> setStatus = new HashSet<>(listOfOperationStatus);
        listOfOperationStatus.clear();
        listOfOperationStatus.addAll(setStatus);

        // Create field OP Name with value
        for (String tempOpName : listOfOperationName) {
            Map<String, Object> tempObjName = new HashMap<>();
            tempObjName.put("OPERATION_NAME", tempOpName);
            for (String tempOpStatus : listOfOperationStatus) {
                tempObjName.put(tempOpStatus, 0);
            }
            result.add(tempObjName);
        }

        Gson gsonResult = new Gson();
        LOGGER.info("Json response : {}", gsonResult.toJson(result));

        return result;
    }

If you have ideas how to do it, that would be great! Many thanks !

Upvotes: 0

Views: 85

Answers (1)

Sergey Prokofiev
Sergey Prokofiev

Reputation: 1885

With these two helper methods

private static Map<String, Object> transform(Map<String, Object> initial) {
    Map<String, Object> transformed = new HashMap<>();
    transformed.put("OPERATION_NAME", (String) initial.get("OPERATION_NAME"));
    transformed.put("READY", 0);
    transformed.put("NEW", 0);
    transformed.put("DONE", 0);
    transformed.put((String) initial.get("OPERATION_STATUS"),
                    Integer.valueOf((String) initial.get("COUNT(1)")));
    return transformed;
}

private static Map<String, Object> mergeMaps(Map<String, Object> left, Map<String, Object> right) {
    for (Entry<String, Object> re : right.entrySet()) {
        if (!"OPERATION_NAME".equals(re.getKey())) {
            left.merge(re.getKey(), re.getValue(), (l, r) -> {
                Integer res = 0;
                res += (Integer) l;
                res += (Integer) r;
                return res;
            });
        }
    }
    return left;
}

you can easily make your transformation

List<Map<String, Object>> output = resDB.stream().map(m -> transform(m)).collect(Collectors.collectingAndThen(
        Collectors.toMap(m -> (String) m.get("OPERATION_NAME"), Function.identity(), (l, r) -> mergeMaps(l, r)),
        m -> new ArrayList<>(m.values())));

Hope it helps!

Upvotes: 1

Related Questions