diff --git a/README.md b/README.md index 61193ae7..4c0c2c17 100644 --- a/README.md +++ b/README.md @@ -85,20 +85,21 @@ Functions Functions can be invoked at the tail end of a path - the input to a function is the output of the path expression. The function output is dictated by the function itself. -| Function | Description | Output type | -|:----------|:-------------------------------------------------------------------------------------|:---------------------| -| min() | Provides the min value of an array of numbers | Double | -| max() | Provides the max value of an array of numbers | Double | -| avg() | Provides the average value of an array of numbers | Double | -| stddev() | Provides the standard deviation value of an array of numbers | Double | -| length() | Provides the length of an array | Integer | -| sum() | Provides the sum value of an array of numbers | Double | -| keys() | Provides the property keys (An alternative for terminal tilde `~`) | `Set` | -| concat(X) | Provides a concatinated version of the path output with a new item | like input | -| append(X) | add an item to the json path output array | like input | -| first() | Provides the first item of an array | Depends on the array | -| last() | Provides the last item of an array | Depends on the array | -| index(X) | Provides the item of an array of index: X, if the X is negative, take from backwards | Depends on the array | +| Function | Description | Output type | +|:-----------|:-------------------------------------------------------------------------------------|:---------------------| +| min() | Provides the min value of an array of numbers | Double | +| max() | Provides the max value of an array of numbers | Double | +| avg() | Provides the average value of an array of numbers | Double | +| stddev() | Provides the standard deviation value of an array of numbers | Double | +| length() | Provides the length of an array | Integer | +| sum() | Provides the sum value of an array of numbers | Double | +| keys() | Provides the property keys (An alternative for terminal tilde `~`) | `Set` | +| concat(X) | Provides a concatinated version of the path output with a new item | like input | +| append(X) | add an item to the json path output array | like input | +| first() | Provides the first item of an array | Depends on the array | +| last() | Provides the last item of an array | Depends on the array | +| index(X) | Provides the item of an array of index: X, if the X is negative, take from backwards | Depends on the array | +| distinct() | Provides the unique items of an array | Depends on the array | Filter Operators ----------------- diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java index 3a31151f..0731d022 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java @@ -8,6 +8,7 @@ import com.jayway.jsonpath.internal.function.numeric.Min; import com.jayway.jsonpath.internal.function.numeric.StandardDeviation; import com.jayway.jsonpath.internal.function.numeric.Sum; +import com.jayway.jsonpath.internal.function.sequence.Distinct; import com.jayway.jsonpath.internal.function.sequence.First; import com.jayway.jsonpath.internal.function.sequence.Index; import com.jayway.jsonpath.internal.function.sequence.Last; @@ -53,6 +54,7 @@ public class PathFunctionFactory { // Sequential Functions map.put("first", First.class); map.put("last", Last.class); + map.put("distinct", Distinct.class); map.put("index", Index.class); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/sequence/Distinct.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/sequence/Distinct.java new file mode 100644 index 00000000..17239fac --- /dev/null +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/sequence/Distinct.java @@ -0,0 +1,31 @@ +package com.jayway.jsonpath.internal.function.sequence; + +import com.jayway.jsonpath.JsonPathException; +import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.PathRef; +import com.jayway.jsonpath.internal.function.Parameter; +import com.jayway.jsonpath.internal.function.PathFunction; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Take the unique items from collection of JSONArray + * + * Created by PavelSakharchuk on 21/09/23 + */ +public class Distinct implements PathFunction { + + @Override + public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List parameters) { + if(ctx.configuration().jsonProvider().isArray(model)){ + Iterable objects = ctx.configuration().jsonProvider().toIterable(model); + Set objectSet = new HashSet<>(); + objects.forEach(objectSet::add); + + return new ArrayList<>(objectSet); + } + throw new JsonPathException("Aggregation function attempted to calculate value using empty array"); + } +} diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java index b26a2b8f..28694227 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java @@ -13,7 +13,7 @@ */ public class BaseFunctionTest { protected static final String NUMBER_SERIES = "{\"empty\": [], \"numbers\" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}"; - protected static final String TEXT_SERIES = "{\"urls\": [\"http://api.worldbank.org/countries/all/?format=json\", \"http://api.worldbank.org/countries/all/?format=json\"], \"text\" : [ \"a\", \"b\", \"c\", \"d\", \"e\", \"f\" ]}"; + protected static final String TEXT_SERIES = "{\"urls\": [\"http://api.worldbank.org/countries/all/?format=json\", \"http://api.worldbank.org/countries/all/?format=json\"], \"text\" : [ \"a\", \"b\", \"c\", \"d\", \"d\", \"e\", \"f\" ]}"; protected static final String TEXT_AND_NUMBER_SERIES = "{\"text\" : [ \"a\", \"b\", \"c\", \"d\", \"e\", \"f\" ], \"numbers\" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}"; /** diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/SequentialPathFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/SequentialPathFunctionTest.java index 70b2b953..2b9eec78 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/SequentialPathFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/SequentialPathFunctionTest.java @@ -2,6 +2,7 @@ import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.Configurations; +import java.util.Arrays; import org.junit.Test; /** @@ -10,6 +11,7 @@ * -first * -last * -index(X) + * -distinct * * Created by git9527 on 6/11/22. */ @@ -50,4 +52,9 @@ public void testIndexOfText() throws Exception { verifyFunction(conf, "$.text.index(-1)", TEXT_SERIES, "f"); verifyFunction(conf, "$.text.index(1)", TEXT_SERIES, "b"); } + + @Test + public void testDistinctOfText() throws Exception { + verifyFunction(conf, "$.text.distinct()", TEXT_SERIES, Arrays.asList("a", "b", "c", "d", "e", "f")); + } }