Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(enhancement) - extend min/max #357

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SimpleTimeZone;
Expand Down Expand Up @@ -1291,32 +1292,85 @@ public JsonNode call(JsonNode input, JsonNode[] arguments) {

public static class Min extends AbstractFunction {
public Min() {
super("min", 2, 2);
super("min", 0, 1_000);
}

public JsonNode call(JsonNode input, JsonNode[] arguments) {
// this works because null is the smallest of all values
if (ComparisonOperator.compare(arguments[0], arguments[1], null) < 0)
return arguments[0];
else
return arguments[1];
if (null == arguments || arguments.length == 0) {
return NullNode.instance;
}

JsonNode minNode = arguments[0];
if (1 == arguments.length) {
if (!minNode.isArray()) {
return minNode;
}
JsonNode nodes = minNode;
if (nodes.isEmpty()) {
return NullNode.instance;
}
minNode = nodes.get(0);
if (1 == nodes.size()) {
return minNode;
}
Iterator<JsonNode> it = nodes.elements();
minNode = it.next();
while (it.hasNext()) {
JsonNode node = it.next();
minNode = ComparisonOperator.compare(minNode, node, null) < 0 ? minNode : node;
}

return minNode;
}

for (JsonNode node : arguments) {
minNode = ComparisonOperator.compare(minNode, node, null) < 0 ? minNode : node;
}

return minNode;
}
}

// ===== MAX

public static class Max extends AbstractFunction {
public Max() {
super("max", 2, 2);
super("max", 0, 1_000);
}

public JsonNode call(JsonNode input, JsonNode[] arguments) {
if (arguments[0].isNull() || arguments[1].isNull())
if (null == arguments || arguments.length == 0) {
return NullNode.instance;
else if (ComparisonOperator.compare(arguments[0], arguments[1], null) > 0)
return arguments[0];
else
return arguments[1];
}

JsonNode maxNode = arguments[0];
if (1 == arguments.length) {
if (!maxNode.isArray()) {
return maxNode;
}
JsonNode nodes = maxNode;
if (nodes.isEmpty()) {
return NullNode.instance;
}
maxNode = nodes.get(0);
if (1 == nodes.size()) {
return maxNode;
}
Iterator<JsonNode> it = nodes.elements();
maxNode = it.next();
while (it.hasNext()) {
JsonNode node = it.next();
maxNode = ComparisonOperator.compare(maxNode, node, null) > 0 ? maxNode : node;
}

return maxNode;
}

for (JsonNode node : arguments) {
maxNode = ComparisonOperator.compare(maxNode, node, null) > 0 ? maxNode : node;
}

return maxNode;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static double compare(JsonNode v1, JsonNode v2, Location location) {
} else if (v1.isTextual() && v2.isTextual()) {
String s1 = v1.asText();
String s2 = v2.asText();
return (double) s1.compareTo(s2);
return s1.compareTo(s2);

} else if (v1.isNull() || v2.isNull()) {
// null is equal to itself, and considered the smallest of all
Expand Down
70 changes: 70 additions & 0 deletions core/src/test/resources/function-tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,21 @@
"input" : "null",
"output": "\"00000000-0000-0000-0000-000000000000\""
},
{
"query": "min()",
"input" : "null",
"output": "null"
},
{
"query": "min(null)",
"input" : "null",
"output": "null"
},
{
"query": "min(1)",
"input" : "null",
"output": "1"
},
{
"query": "min(1, 2)",
"input" : "null",
Expand All @@ -1247,6 +1262,41 @@
"input" : "null",
"output": "null"
},
{
"query": "min(99)",
"input" : "null",
"output": "99"
},
{
"query": "min([])",
"input" : "null",
"output": "null"
},
{
"query": "min([99])",
"input" : "null",
"output": "99"
},
{
"query": "min([-99, 37, -234])",
"input" : "null",
"output": "-234"
},
{
"query": "max()",
"input" : "null",
"output": "null"
},
{
"query": "max(null)",
"input" : "null",
"output": "null"
},
{
"query": "max(1)",
"input" : "null",
"output": "1"
},
{
"query": "max(1, 2)",
"input" : "null",
Expand All @@ -1265,8 +1315,28 @@
{
"query": "max(null, 0)",
"input" : "null",
"output": "0"
},
{
"query": "max(99)",
"input" : "null",
"output": "99"
},
{
"query": "max([])",
"input" : "null",
"output": "null"
},
{
"query": "max([99])",
"input" : "null",
"output": "99"
},
{
"query": "max([99, 37, -234])",
"input" : "null",
"output": "99"
},
{
"query" : "hash-int(.)",
"input" : "\"\"",
Expand Down
36 changes: 24 additions & 12 deletions functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,42 @@ fallback(.not_existing_key, .another_not_existing, 1) => 1
fallback(null, [], {}, "value") => "value"
```

### _min(arg1, arg2) -> value_
### _min(args) -> value_

Returns the argument that compares as the smallest. If one argument is
`null` the result is `null`.
`args` can be `null`, 1 or more items of the same kind, such as numbers, characters or Strings.
It can even be an array of items of the same kind.

Returns the lowest item, or `null`.
`null` is considered the lowest value, regardless of the other items.

Examples:

```
min(10, 1) -> 1
min("a", "b") -> "a"
min(10, null) -> null
min(10, 1) -> 1
min("a", "b") -> "a"
min(10, null) -> null
min(10) -> 10
min([7]) -> 7
max([5,6,7,8]) -> 5
```

### _max(arg1, arg2) -> value_
### _max(args) -> value_

`args` can be `null`, 1 or more items of the same kind, such as numbers, characters or Strings.
It can even be an array of items of the same kind.

Returns the argument that compares as the largest. If one argument is
`null` the result is `null`.
Returns the largest item.
`null` is considered the lowest value, regardless of the other items.

Examples:

```
max(10, 1) -> 10
max("a", "b") -> "b"
max(10, null) -> null
max(10, 1) -> 10
max("a", "b") -> "b"
max(10, null) -> 10
max(17) -> 17
max([26]) -> 26
max([1,2,3,4]) -> 4
```

<!-- NUMERIC ===============================================================-->
Expand Down
Loading