Traditional functional language think of reduce in term of initial value and accumulator over the list. In Java things are more complicate as it require a BinaryOperator.
I would like to know if we have a better way of writing this kind of function:
public JsonObject growPath(final JsonObject obj) {
// paths is a list of string
return this.paths.stream().reduce(obj, (child, path) -> {
if (!child.containsKey(path) || !(child.get(path) instanceof JsonObject)) {
// We do override anything that is not an object since the path
// specify that it should be an object.
child.put(path, JsonObject.create());
}
return child.getObject(path);
} , (first, last) -> {
return last;
});
}
I would like to avoid the BinaryOperator argument. Should I use something different than reduce ?
You are using the wrong tool for the job. You are performing an action that modifies obj, which has nothing to do with reduction at all. If we ignore the modifying aspect, this operation is a left-fold, which Streams do not support (in general). You can only implement it using reduce, if the function is associative, which your function is not. So you best implement it without Streams:
public JsonObject growPath(JsonObject obj) {
for(String path: this.paths)
obj = (JsonObject)obj.compute(path,
(key,child)->child instanceof JsonObject? child: JsonObject.create());
return obj;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With