Skip to content

Commit d312fa2

Browse files
committed
java-1.2.1 js-core-1.8.0 js-1.8.0 - fix min/max 'by' behavior, add indexof and findindex functions
1 parent 1c7e86f commit d312fa2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+731
-163
lines changed

java/json-transform/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group 'co.nlighten'
12-
version = '1.1.2'
12+
version = '1.2.1'
1313

1414
ext {
1515
gsonVersion = "2.10.1"

java/json-transform/src/main/java/co/nlighten/jsontransform/TransformerFunctions.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public class TransformerFunctions implements TransformerFunctionsAdapter {
2828

2929
static {
3030
registerFunctions(
31-
Map.entry("all",new TransformerFunctionEvery()),
31+
Map.entry("all",new TransformerFunctionEvery()), // * alias for every
3232
Map.entry("and", new TransformerFunctionAnd()),
33-
Map.entry("any", new TransformerFunctionSome()),
33+
Map.entry("any", new TransformerFunctionSome()), // * alias for some
3434
Map.entry("at",new TransformerFunctionAt()),
3535
Map.entry("avg",new TransformerFunctionAvg()),
3636
Map.entry("base64", new TransformerFunctionBase64()),
@@ -49,13 +49,15 @@ public class TransformerFunctions implements TransformerFunctionsAdapter {
4949
Map.entry("every",new TransformerFunctionEvery()),
5050
Map.entry("filter", new TransformerFunctionFilter()),
5151
Map.entry("find", new TransformerFunctionFind()),
52+
Map.entry("findindex", new TransformerFunctionFindIndex()),
5253
Map.entry("first", new TransformerFunctionCoalesce()), // * alias for coalesce
5354
Map.entry("flat", new TransformerFunctionFlat()),
5455
Map.entry("flatten",new TransformerFunctionFlatten()),
5556
Map.entry("form", new TransformerFunctionForm()),
5657
Map.entry("formparse", new TransformerFunctionFormParse()),
5758
Map.entry("group", new TransformerFunctionGroup()),
5859
Map.entry("if", new TransformerFunctionIf()),
60+
Map.entry("indexof", new TransformerFunctionIndexOf()),
5961
Map.entry("is", new TransformerFunctionIs()),
6062
Map.entry("isnull", new TransformerFunctionIsNull()),
6163
Map.entry("join", new TransformerFunctionJoin()),
@@ -87,6 +89,7 @@ public class TransformerFunctions implements TransformerFunctionsAdapter {
8789
Map.entry("range", new TransformerFunctionRange()),
8890
Map.entry("raw", new TransformerFunctionRaw()),
8991
Map.entry("reduce", new TransformerFunctionReduce()),
92+
Map.entry("repeat", new TransformerFunctionRepeat()),
9093
Map.entry("replace", new TransformerFunctionReplace()),
9194
Map.entry("reverse", new TransformerFunctionReverse()),
9295
Map.entry("slice", new TransformerFunctionSlice()),

java/json-transform/src/main/java/co/nlighten/jsontransform/adapters/JsonAdapter.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,26 @@ public String getAsString(Object value) {
182182
*/
183183
public abstract Boolean getBoolean(Object value);
184184

185+
/**
186+
* Convert the specified object to one of supported types
187+
* @param type type of object to extract as ("NUMBER" / "BOOLEAN" / "STRING" / "AUTO")
188+
* @param value the value
189+
* @return the extracted value
190+
*/
191+
public Object getAs(String type, Object value) {
192+
if ("NUMBER".equals(type) || isJsonNumber(value)) {
193+
return getNumberAsBigDecimal(value);
194+
}
195+
if ("BOOLEAN".equals(type) || isJsonBoolean(value)) {
196+
return getBoolean(value);
197+
}
198+
if ("STRING".equals(type) || isJsonString(value)) {
199+
return getAsString(value);
200+
}
201+
// "AUTO"
202+
return value;
203+
}
204+
185205
/**
186206
* Compares two Json elements
187207
* @param a the first Json element

java/json-transform/src/main/java/co/nlighten/jsontransform/functions/TransformerFunctionAvg.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public Object apply(FunctionContext context) {
2222
var streamer = context.getJsonElementStreamer(null);
2323
if (streamer == null || streamer.knownAsEmpty())
2424
return null;
25+
var hasBy = context.has("by");
2526
var by = context.getJsonElement( "by", false);
2627
var _default = Objects.requireNonNullElse(context.getBigDecimal("default"), BigDecimal.ZERO);
2728
var size = new AtomicInteger(0);
@@ -30,7 +31,7 @@ public Object apply(FunctionContext context) {
3031
var result = streamer.stream()
3132
.map(t -> {
3233
size.getAndIncrement();
33-
var res = !adapter.isNull(by) ? context.transformItem(by, t) : t;
34+
var res = hasBy ? context.transformItem(by, t) : t;
3435
return adapter.isNull(res) ? _default : adapter.getNumberAsBigDecimal(res);
3536
})
3637
.reduce(identity, BigDecimal::add)

java/json-transform/src/main/java/co/nlighten/jsontransform/functions/TransformerFunctionDistinct.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ public TransformerFunctionDistinct() {
1919
public Object apply(FunctionContext context) {
2020
var streamer = context.getJsonElementStreamer(null);
2121
if (streamer == null) return null;
22-
var by = context.getJsonElement( "by", false);
22+
var hasBy = context.has("by");
2323
var adapter = context.getAdapter();
24-
if (!adapter.isNull(by)) {
24+
if (hasBy) {
25+
var by = context.getJsonElement( "by", false);
2526
return JsonElementStreamer.fromTransformedStream(context, streamer.stream()
2627
.map(item -> {
2728
var toDistinctBy = context.transformItem(by, item);

java/json-transform/src/main/java/co/nlighten/jsontransform/functions/TransformerFunctionFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class TransformerFunctionFilter extends TransformerFunction {
1010
public TransformerFunctionFilter() {
1111
super(FunctionDescription.of(
1212
Map.of(
13-
"by", ArgumentType.of(ArgType.Transformer).position(0).defaultIsNull(true)
13+
"by", ArgumentType.of(ArgType.Transformer).position(0)
1414
)
1515
));
1616
}

java/json-transform/src/main/java/co/nlighten/jsontransform/functions/TransformerFunctionFind.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ public Object apply(FunctionContext context) {
1717
var streamer = context.getJsonElementStreamer(null);
1818
if (streamer == null)
1919
return null;
20+
var hasBy = context.has("by");
2021
var by = context.getJsonElement("by", false);
2122
var index = new AtomicInteger(0);
2223
var adapter = context.getAdapter();
2324
return streamer.stream()
2425
.filter(item -> {
26+
if (!hasBy) {
27+
return adapter.isTruthy(item);
28+
}
2529
var condition = context.transformItem(by, item, index.getAndIncrement());
2630
return adapter.isTruthy(condition);
2731
})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package co.nlighten.jsontransform.functions;
2+
3+
import co.nlighten.jsontransform.functions.common.*;
4+
5+
import java.util.Iterator;
6+
import java.util.Map;
7+
8+
public class TransformerFunctionFindIndex extends TransformerFunction {
9+
public TransformerFunctionFindIndex() {
10+
super(FunctionDescription.of(
11+
Map.of(
12+
"by", ArgumentType.of(ArgType.Transformer).position(0).defaultIsNull(true)
13+
)));
14+
}
15+
@Override
16+
public Object apply(FunctionContext context) {
17+
var streamer = context.getJsonElementStreamer(null);
18+
if (streamer == null)
19+
return null;
20+
var hasBy = context.has("by");
21+
var by = context.getJsonElement("by", false);
22+
var adapter = context.getAdapter();
23+
var i = 0;
24+
boolean found = false;
25+
for (Iterator<?> iter = streamer.stream().iterator(); iter.hasNext();) {
26+
var item = iter.next();
27+
if (!hasBy) {
28+
if (adapter.isTruthy(item)) {
29+
found = true;
30+
break;
31+
}
32+
}
33+
var condition = context.transformItem(by, item, i++);
34+
if (adapter.isTruthy(condition)) {
35+
found = true;
36+
break;
37+
}
38+
}
39+
return found ? i - 1 : -1;
40+
}
41+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package co.nlighten.jsontransform.functions;
2+
3+
import co.nlighten.jsontransform.functions.common.*;
4+
5+
import java.util.Map;
6+
import java.util.concurrent.atomic.AtomicInteger;
7+
8+
public class TransformerFunctionIndexOf extends TransformerFunction {
9+
public TransformerFunctionIndexOf() {
10+
super(FunctionDescription.of(
11+
Map.of(
12+
"of", ArgumentType.of(ArgType.Any).position(0)
13+
)));
14+
}
15+
@Override
16+
public Object apply(FunctionContext context) {
17+
var streamer = context.getJsonElementStreamer(null);
18+
if (streamer == null)
19+
return null;
20+
var of = context.getJsonElement("of");
21+
var index = new AtomicInteger(0);
22+
var adapter = context.getAdapter();
23+
return streamer.stream()
24+
.sequential()
25+
.peek(item -> index.incrementAndGet())
26+
.anyMatch(item -> adapter.areEqual(item, of)) ? index.get() - 1 : -1;
27+
}
28+
}

java/json-transform/src/main/java/co/nlighten/jsontransform/functions/TransformerFunctionMax.java

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import co.nlighten.jsontransform.functions.common.*;
44

5+
import java.util.ArrayList;
56
import java.util.Comparator;
7+
import java.util.List;
68
import java.util.Map;
79

810
public class TransformerFunctionMax extends TransformerFunction {
@@ -21,36 +23,30 @@ public Object apply(FunctionContext context) {
2123
var streamer = context.getJsonElementStreamer(null);
2224
if (streamer == null || streamer.knownAsEmpty())
2325
return null;
24-
var by = context.getJsonElement("by", true);
25-
26+
var hasBy = context.has("by");
2627
var type = context.getEnum("type");
27-
2828
var def = context.getJsonElement("default",true);
29+
2930
var adapter = context.getAdapter();
30-
Comparator<Object> comparator = type == null || "AUTO".equals(type)
31-
? adapter.comparator()
32-
: switch (type) {
33-
case "NUMBER" -> Comparator.comparing(adapter::getNumberAsBigDecimal);
34-
case "BOOLEAN" -> Comparator.comparing(adapter::getBoolean);
35-
//case "string"
36-
default -> Comparator.comparing(adapter::getAsString);
37-
};
38-
var result = streamer.stream()
39-
.map(t -> {
40-
var res = !adapter.isNull(by) ? context.transformItem(by, t) : t;
41-
return (adapter.isNull(res)) ? def : res;
42-
})
43-
.max(comparator);
44-
if (result.isPresent()) {
45-
var resultValue = result.get();
46-
if ("NUMBER".equals(type) || adapter.isJsonNumber(resultValue)) {
47-
return adapter.getNumberAsBigDecimal(resultValue);
48-
} else if ("BOOLEAN".equals(type) || adapter.isJsonBoolean(resultValue)) {
49-
return adapter.getBoolean(resultValue);
50-
} else {
51-
return adapter.getAsString(resultValue);
52-
}
31+
if (!hasBy) {
32+
var comparator = FunctionHelpers.createComparator(adapter, type);
33+
var result = streamer.stream()
34+
.map(t -> adapter.isNull(t) ? def : t)
35+
.max(comparator);
36+
return result.isPresent() ? adapter.getAs(type, result.get()) : adapter.jsonNull();
37+
} else {
38+
var by = context.getJsonElement("by", false);
39+
var comparator = CompareBy.createByComparator(adapter, 0, type);
40+
var result = streamer.stream()
41+
.map(item -> {
42+
var cb = new CompareBy(item);
43+
var t = context.transformItem(by, item);
44+
cb.by = new ArrayList<>();
45+
cb.by.add(adapter.isNull(t) ? def : t);
46+
return cb;
47+
})
48+
.max(comparator);
49+
return result.isPresent() ? adapter.getAs(type, result.get().value) : adapter.jsonNull();
5350
}
54-
return adapter.jsonNull();
5551
}
5652
}

0 commit comments

Comments
 (0)