Добавлена функция functional::dropwhile

This commit is contained in:
Victor 2016-08-01 14:48:10 +03:00
parent f048da8325
commit 4e5fc7b738
2 changed files with 18 additions and 34 deletions

View File

@ -25,6 +25,7 @@ public final class functional implements Module {
Functions.set("filter", new functional_filter(false)); Functions.set("filter", new functional_filter(false));
Functions.set("sortby", new functional_sortby()); Functions.set("sortby", new functional_sortby());
Functions.set("takewhile", new functional_filter(true)); Functions.set("takewhile", new functional_filter(true));
Functions.set("dropwhile", new functional_dropwhile());
Functions.set("chain", new functional_chain()); Functions.set("chain", new functional_chain());
Functions.set("combine", new functional_combine()); Functions.set("combine", new functional_combine());

View File

@ -2,52 +2,35 @@ package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; public final class functional_dropwhile implements Function {
public final class functional_filter implements Function {
@Override @Override
public Value execute(Value... args) { public Value execute(Value... args) {
Arguments.check(2, args.length); Arguments.check(2, args.length);
if (args[0].type() != Types.ARRAY) {
throw new TypeException("Array expected in first argument");
}
if (args[1].type() != Types.FUNCTION) { if (args[1].type() != Types.FUNCTION) {
throw new TypeException("Function expected in second argument"); throw new TypeException("Function expected in second argument");
} }
final Value container = args[0]; final Value container = args[0];
final Function consumer = ((FunctionValue) args[1]).getValue(); final Function predicate = ((FunctionValue) args[1]).getValue();
if (container.type() == Types.ARRAY) { return dropWhileArray((ArrayValue) container, predicate);
return filterArray((ArrayValue) container, consumer);
} }
if (container.type() == Types.MAP) { private Value dropWhileArray(ArrayValue array, Function predicate) {
return filterMap((MapValue) container, consumer); int skipCount = 0;
}
throw new TypeException("Invalid first argument. Array or map expected");
}
private Value filterArray(ArrayValue array, Function predicate) {
final int size = array.size();
final List<Value> values = new ArrayList<Value>(size);
for (Value value : array) { for (Value value : array) {
if (predicate.execute(value) != NumberValue.ZERO) { if (predicate.execute(value) != NumberValue.ZERO)
values.add(value); skipCount++;
} else break;
}
final int newSize = values.size();
return new ArrayValue(values.toArray(new Value[newSize]));
} }
private Value filterMap(MapValue map, Function predicate) { final int size = array.size();
final MapValue result = new MapValue(map.size()); final Value[] result = new Value[size - skipCount];
for (Map.Entry<Value, Value> element : map) { System.arraycopy(array.getCopyElements(), skipCount, result, 0, result.length);
if (predicate.execute(element.getKey(), element.getValue()) != NumberValue.ZERO) { return new ArrayValue(result);
result.set(element.getKey(), element.getValue());
}
}
return result;
} }
} }