Добавлена функция 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("sortby", new functional_sortby());
Functions.set("takewhile", new functional_filter(true));
Functions.set("dropwhile", new functional_dropwhile());
Functions.set("chain", new functional_chain());
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.lib.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class functional_filter implements Function {
public final class functional_dropwhile implements Function {
@Override
public Value execute(Value... args) {
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) {
throw new TypeException("Function expected in second argument");
}
final Value container = args[0];
final Function consumer = ((FunctionValue) args[1]).getValue();
if (container.type() == Types.ARRAY) {
return filterArray((ArrayValue) container, consumer);
}
if (container.type() == Types.MAP) {
return filterMap((MapValue) container, consumer);
}
throw new TypeException("Invalid first argument. Array or map expected");
final Function predicate = ((FunctionValue) args[1]).getValue();
return dropWhileArray((ArrayValue) container, predicate);
}
private Value filterArray(ArrayValue array, Function predicate) {
final int size = array.size();
final List<Value> values = new ArrayList<Value>(size);
private Value dropWhileArray(ArrayValue array, Function predicate) {
int skipCount = 0;
for (Value value : array) {
if (predicate.execute(value) != NumberValue.ZERO) {
values.add(value);
}
if (predicate.execute(value) != NumberValue.ZERO)
skipCount++;
else break;
}
final int newSize = values.size();
return new ArrayValue(values.toArray(new Value[newSize]));
}
private Value filterMap(MapValue map, Function predicate) {
final MapValue result = new MapValue(map.size());
for (Map.Entry<Value, Value> element : map) {
if (predicate.execute(element.getKey(), element.getValue()) != NumberValue.ZERO) {
result.set(element.getKey(), element.getValue());
}
}
return result;
final int size = array.size();
final Value[] result = new Value[size - skipCount];
System.arraycopy(array.getCopyElements(), skipCount, result, 0, result.length);
return new ArrayValue(result);
}
}