Добавлено комбинирование функий и flatmap

This commit is contained in:
Victor 2016-01-19 14:59:04 +02:00
parent 47dfae5740
commit 02fe4b6e0c
5 changed files with 81 additions and 42 deletions

View File

@ -126,6 +126,11 @@ squares = map(nums, def(x) = x * x)
foreach(squares, ::echo)
println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
nums = [[1, 2], [3], [], [4, 5]]
nums = flatmap(nums, IDENTITY)
println "flatmap"
foreach(nums, ::echo)
use "http"
/*http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) {
@ -165,3 +170,12 @@ def fact2(n) = match n {
println fact1(6)
println fact2(6)
class = {
"add": def(a, b) = a + b,
"sub": def(a, b) = a - b,
"mul": def(a, b) = a * b,
"div": def(a, b) = a / b
}
println class.add(2, class.mul(2, 2))

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.TypeException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
*
@ -39,6 +40,11 @@ public final class ArrayValue implements Value, Iterable<Value> {
System.arraycopy(elements, 0, this.elements, 0, elements.length);
}
public ArrayValue(List<Value> values) {
final int size = values.size();
this.elements = values.toArray(new Value[size]);
}
public ArrayValue(ArrayValue array) {
this(array.elements);
}

View File

@ -13,7 +13,12 @@ public final class functional implements Module {
public void init() {
Functions.set("foreach", new functional_foreach());
Functions.set("map", new functional_map());
Functions.set("flatmap", new functional_flatmap());
Functions.set("reduce", new functional_reduce());
Functions.set("filter", new functional_filter());
Functions.set("combine", new functional_combine());
Variables.set("IDENTITY", new FunctionValue(args -> args[0]));
}
}

View File

@ -1,55 +1,29 @@
package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*;
import java.util.Map;
public final class functional_map implements Function {
public final class functional_combine implements Function {
@Override
public Value execute(Value... args) {
if (args.length < 2) throw new RuntimeException("At least two args expected");
if (args.length < 1) throw new ArgumentsMismatchException("At least one arg expected");
final Value container = args[0];
if (container.type() == Types.ARRAY) {
if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg");
Function result = null;
for (Value arg : args) {
if (arg.type() != Types.FUNCTION) {
throw new TypeException(arg.toString() + " is not a function");
}
final Function mapper = ((FunctionValue) args[1]).getValue();
return mapArray((ArrayValue) container, mapper);
final Function current = result;
final Function next = ((FunctionValue) arg).getValue();
result = fArgs -> {
if (current == null) return next.execute(fArgs);
return next.execute(current.execute(fArgs));
};
}
if (container.type() == Types.MAP) {
if (args[1].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in second arg");
}
if (args[2].type() != Types.FUNCTION) {
throw new RuntimeException("Function expected in third arg");
}
final Function keyMapper = ((FunctionValue) args[1]).getValue();
final Function valueMapper = ((FunctionValue) args[2]).getValue();
return mapMap((MapValue) container, keyMapper, valueMapper);
}
throw new RuntimeException("Invalid first argument. Array or map exprected");
return new FunctionValue(result);
}
private Value mapArray(ArrayValue array, Function mapper) {
final int size = array.size();
final ArrayValue result = new ArrayValue(size);
for (int i = 0; i < size; i++) {
result.set(i, mapper.execute(array.get(i)));
}
return result;
}
private Value mapMap(MapValue map, Function keyMapper, Function valueMapper) {
final MapValue result = new MapValue(map.size());
for (Map.Entry<Value, Value> element : map) {
final Value newKey = keyMapper.execute(element.getKey());
final Value newValue = valueMapper.execute(element.getValue());
result.set(newKey, newValue);
}
return result;
}
}

View File

@ -0,0 +1,40 @@
package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*;
import java.util.ArrayList;
import java.util.List;
public final class functional_flatmap implements Function {
@Override
public Value execute(Value... args) {
if (args.length < 2) throw new ArgumentsMismatchException("At least two arguments expected");
if (args[0].type() != Types.ARRAY) {
throw new TypeException("Array expected in first argument");
}
if (args[1].type() != Types.FUNCTION) {
throw new TypeException("Function expected in second argument");
}
final Function mapper = ((FunctionValue) args[1]).getValue();
return flatMapArray((ArrayValue) args[0], mapper);
}
private Value flatMapArray(ArrayValue array, Function mapper) {
final List<Value> values = new ArrayList<>();
final int size = array.size();
for (int i = 0; i < size; i++) {
final Value inner = mapper.execute(array.get(i));
if (inner.type() != Types.ARRAY) {
throw new TypeException("Array expected " + inner);
}
for (Value value : (ArrayValue) inner) {
values.add(value);
}
}
return new ArrayValue(values);
}
}