Skip to content

Commit

Permalink
implemented the standard-function called filter
Browse files Browse the repository at this point in the history
  • Loading branch information
BlvckBytes committed Jan 23, 2025
1 parent b814ccb commit 4c9aa3a
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 5 deletions.
18 changes: 17 additions & 1 deletion README-X.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ list_of(value...?: Object): List<?>

### map

Iterate over a collection while mapping each iteration through a lambda function, who's result
Iterate over a collection while mapping each iteration through a lambda function, whose result
is being appended to the final result list.

| Argument | Description |
Expand All @@ -427,6 +427,22 @@ map(items: Collection<?>, mapper: (item: Object, index: Number) => String, fallb

<!-- #include src/test/java/me/blvckbytes/gpeee/std/MapFunctionTests.java -->

### filter

Iterate over a collection while mapping each item through a lambda function, whose result
is being interpreted as a filter predicate.

| Argument | Description |
|-----------|--------------------------------------|
| items | Collection to iterate |
| mapper | Lambda function to filter items with |

```
filter(items: Collection<?>, mapper: (item: Object, index: Number) => String): List<?>
```

<!-- #include src/test/java/me/blvckbytes/gpeee/std/FilterFunctionTests.java -->

### map_of

Create a list from a variable amount of scalar input value pairs.
Expand Down
66 changes: 62 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ want to integrate into your next project.
- [list](#list)
- [list_of](#list_of)
- [map](#map)
- [filter](#filter)
- [map_of](#map_of)
- [print](#print)
- [r_index](#r_index)
Expand Down Expand Up @@ -136,6 +137,11 @@ public interface IExpressionEvaluator {
*/
Object evaluateExpression(AExpression expression, IEvaluationEnvironment environment) throws AEvaluatorError;

/**
* Get a copy of the evaluator's base environment to be safely modified and built by the caller
*/
EvaluationEnvironmentBuilder getBaseEnvironment();

}
```
</details>
Expand Down Expand Up @@ -269,16 +275,21 @@ public class EvaluationEnvironmentBuilder {
}

public IEvaluationEnvironment build(@Nullable IEvaluationEnvironment environmentToExtend) {
Map<String, AExpressionFunction> resultingFunctions = new HashMap<>(this.functions);
Map<String, Supplier<?>> resultingLiveVariables = new HashMap<>(this.liveVariables);
Map<String, Object> resultingStaticVariables = new HashMap<>(this.staticVariables);
Map<String, AExpressionFunction> resultingFunctions = new HashMap<>();
Map<String, Supplier<?>> resultingLiveVariables = new HashMap<>();
Map<String, Object> resultingStaticVariables = new HashMap<>();

if (environmentToExtend != null) {
resultingFunctions.putAll(environmentToExtend.getFunctions());
resultingLiveVariables.putAll(environmentToExtend.getLiveVariables());
resultingStaticVariables.putAll(environmentToExtend.getStaticVariables());
}

// Put builder-items last, as to make them prevail over the possibly extended environment
resultingFunctions.putAll(this.functions);
resultingLiveVariables.putAll(this.liveVariables);
resultingStaticVariables.putAll(this.staticVariables);

return new IEvaluationEnvironment() {

@Override
Expand Down Expand Up @@ -1470,7 +1481,7 @@ public class ListOfFunctionTests {

### map

Iterate over a collection while mapping each iteration through a lambda function, who's result
Iterate over a collection while mapping each iteration through a lambda function, whose result
is being appended to the final result list.

| Argument | Description |
Expand Down Expand Up @@ -1527,6 +1538,53 @@ public class MapFunctionTests {
</details>


### filter

Iterate over a collection while mapping each item through a lambda function, whose result
is being interpreted as a filter predicate.

| Argument | Description |
|-----------|--------------------------------------|
| items | Collection to iterate |
| mapper | Lambda function to filter items with |

```
filter(items: Collection<?>, mapper: (item: Object, index: Number) => String): List<?>
```

<details>
<summary>FilterFunctionTests.java</summary>

```java
package me.blvckbytes.gpeee.std;

public class FilterFunctionTests {

@Test
public void shouldRequireArguments() {
new EnvironmentBuilder()
.withStaticVariable("items", Collections.emptyList())
.launch(validator -> {
validator.validateThrows("filter()", InvalidFunctionArgumentTypeError.class);
validator.validateThrows("filter(items)", InvalidFunctionArgumentTypeError.class);
});
}

@Test
public void shouldFilterInputItems() {
new EnvironmentBuilder()
.withStaticVariable("items", Arrays.asList("a", "b", "c", null))
.launch(validator -> {
validator.validate("filter(items, (item) => item != \"a\")", Arrays.asList("b", "c", null));
validator.validate("filter(items, (item) => item != \"c\")", Arrays.asList("a", "b", null));
validator.validate("filter(items, (item) => item != null)", Arrays.asList("a", "b", "c"));
});
}
}
```
</details>


### map_of

Create a list from a variable amount of scalar input value pairs.
Expand Down
1 change: 1 addition & 0 deletions src/main/java/me/blvckbytes/gpeee/GPEEE.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ private void loadStandardFunctions() {
new PrintFunction().registerSelf(this);
new TitleCaseFunction().registerSelf(this);
new MapFunction().registerSelf(this);
new FilterFunction().registerSelf(this);
new DateFormatFunction().registerSelf(this);
new LIndexFunction().registerSelf(this);
new RIndexFunction().registerSelf(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* MIT License
*
* Copyright (c) 2025 BlvckBytes
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package me.blvckbytes.gpeee.functions.std;

import me.blvckbytes.gpeee.functions.AExpressionFunction;
import me.blvckbytes.gpeee.functions.ExpressionFunctionArgument;
import me.blvckbytes.gpeee.functions.IStandardFunctionRegistry;
import me.blvckbytes.gpeee.interpreter.IEvaluationEnvironment;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* Filter collections - filter
*
* Filters a collection of items by running each through a callback expression
* which will map it to a boolean value and then collects passing items in the resulting collection.
*/
public class FilterFunction extends AStandardFunction {

@Override
public Object apply(IEvaluationEnvironment env, List<@Nullable Object> args) {
// Retrieve arguments
Iterable<?> items = nonNull(args, 0);
AExpressionFunction mapper = nonNull(args, 1);

List<Object> result = new ArrayList<>();

// Loop all items with their indices
int c = 0;
for (Object item : items) {
Object mapperResult = mapper.apply(env, Arrays.asList(item, c++));

if (!env.getValueInterpreter().asBoolean(mapperResult))
continue;

result.add(item);
}

return result;
}

@Override
public @Nullable List<ExpressionFunctionArgument> getArguments() {
// filter(items, (it, ind) => (..))
return Arrays.asList(
new ExpressionFunctionArgument("items", "Items to iterate", true, Iterable.class),
new ExpressionFunctionArgument("mapper", "Iteration item mapper function", true, AExpressionFunction.class)
);
}

@Override
public void registerSelf(IStandardFunctionRegistry registry) {
registry.register("filter", this);
}

@Override
public boolean returnsPrimaryResult() {
return true;
}
}
57 changes: 57 additions & 0 deletions src/test/java/me/blvckbytes/gpeee/std/FilterFunctionTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* MIT License
*
* Copyright (c) 2025 BlvckBytes
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package me.blvckbytes.gpeee.std;

import me.blvckbytes.gpeee.EnvironmentBuilder;
import me.blvckbytes.gpeee.error.InvalidFunctionArgumentTypeError;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class FilterFunctionTests {

@Test
public void shouldRequireArguments() {
new EnvironmentBuilder()
.withStaticVariable("items", Collections.emptyList())
.launch(validator -> {
validator.validateThrows("filter()", InvalidFunctionArgumentTypeError.class);
validator.validateThrows("filter(items)", InvalidFunctionArgumentTypeError.class);
});
}

@Test
public void shouldFilterInputItems() {
new EnvironmentBuilder()
.withStaticVariable("items", Arrays.asList("a", "b", "c", null))
.launch(validator -> {
validator.validate("filter(items, (item) => item != \"a\")", Arrays.asList("b", "c", null));
validator.validate("filter(items, (item) => item != \"c\")", Arrays.asList("a", "b", null));
validator.validate("filter(items, (item) => item != null)", Arrays.asList("a", "b", "c"));
});
}
}

0 comments on commit 4c9aa3a

Please sign in to comment.