Добавлены функции std sort и functional sortby

This commit is contained in:
Victor 2016-01-19 17:59:23 +02:00
parent 02fe4b6e0c
commit 5f25d6be07
11 changed files with 112 additions and 2 deletions

View File

@ -130,6 +130,8 @@ nums = [[1, 2], [3], [], [4, 5]]
nums = flatmap(nums, IDENTITY) nums = flatmap(nums, IDENTITY)
println "flatmap" println "flatmap"
foreach(nums, ::echo) foreach(nums, ::echo)
println "sort"
foreach(sort(nums, def(a,b) = b - a), ::echo)
use "http" use "http"

View File

@ -48,6 +48,12 @@ public final class ArrayValue implements Value, Iterable<Value> {
public ArrayValue(ArrayValue array) { public ArrayValue(ArrayValue array) {
this(array.elements); this(array.elements);
} }
public Value[] getCopyElements() {
final Value[] result = new Value[elements.length];
System.arraycopy(elements, 0, result, 0, elements.length);
return result;
}
@Override @Override
public int type() { public int type() {
@ -97,6 +103,15 @@ public final class ArrayValue implements Value, Iterable<Value> {
final ArrayValue other = (ArrayValue) obj; final ArrayValue other = (ArrayValue) obj;
return Arrays.deepEquals(this.elements, other.elements); return Arrays.deepEquals(this.elements, other.elements);
} }
@Override
public int compareTo(Value o) {
if (o.type() == Types.ARRAY) {
final int lengthCompare = Integer.compare(size(), ((ArrayValue) o).size());
if (lengthCompare != 0) return lengthCompare;
}
return asString().compareTo(o.asString());
}
@Override @Override
public String toString() { public String toString() {

View File

@ -53,6 +53,11 @@ public final class FunctionValue implements Value {
return Objects.equals(this.value, other.value); return Objects.equals(this.value, other.value);
} }
@Override
public int compareTo(Value o) {
return asString().compareTo(o.asString());
}
@Override @Override
public String toString() { public String toString() {
return asString(); return asString();

View File

@ -77,6 +77,15 @@ public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
return Objects.equals(this.map, other.map); return Objects.equals(this.map, other.map);
} }
@Override
public int compareTo(Value o) {
if (o.type() == Types.MAP) {
final int lengthCompare = Integer.compare(size(), ((MapValue) o).size());
if (lengthCompare != 0) return lengthCompare;
}
return asString().compareTo(o.asString());
}
@Override @Override
public String toString() { public String toString() {
return asString(); return asString();

View File

@ -51,7 +51,13 @@ public final class NumberValue implements Value {
return Double.doubleToLongBits(this.value) == Double.doubleToLongBits(other.value); return Double.doubleToLongBits(this.value) == Double.doubleToLongBits(other.value);
} }
@Override
public int compareTo(Value o) {
if (o.type() == Types.NUMBER) {
return Double.compare(value, ((NumberValue)o).value);
}
return asString().compareTo(o.asString());
}
@Override @Override
public String toString() { public String toString() {

View File

@ -54,6 +54,14 @@ public final class StringValue implements Value {
return Objects.equals(this.value, other.value); return Objects.equals(this.value, other.value);
} }
@Override
public int compareTo(Value o) {
if (o.type() == Types.STRING) {
return value.compareTo(((StringValue) o).value);
}
return asString().compareTo(o.asString());
}
@Override @Override
public String toString() { public String toString() {
return asString(); return asString();

View File

@ -4,7 +4,7 @@ package com.annimon.ownlang.lib;
* *
* @author aNNiMON * @author aNNiMON
*/ */
public interface Value { public interface Value extends Comparable<Value> {
double asNumber(); double asNumber();

View File

@ -16,6 +16,7 @@ public final class functional implements Module {
Functions.set("flatmap", new functional_flatmap()); Functions.set("flatmap", new functional_flatmap());
Functions.set("reduce", new functional_reduce()); Functions.set("reduce", new functional_reduce());
Functions.set("filter", new functional_filter()); Functions.set("filter", new functional_filter());
Functions.set("sortby", new functional_sortby());
Functions.set("combine", new functional_combine()); Functions.set("combine", new functional_combine());

View File

@ -0,0 +1,27 @@
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.Arrays;
public final class functional_sortby implements Function {
@Override
public Value execute(Value... args) {
if (args.length != 2) throw new ArgumentsMismatchException("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 Value[] elements = ((ArrayValue) args[0]).getCopyElements();
final Function function = ((FunctionValue) args[1]).getValue();
Arrays.sort(elements, (o1, o2) -> function.execute(o1).compareTo(function.execute(o2)));
return new ArrayValue(elements);
}
}

View File

@ -0,0 +1,36 @@
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.Arrays;
public final class std_sort implements Function {
@Override
public Value execute(Value... args) {
if (args.length < 1) throw new ArgumentsMismatchException("At least one argument expected");
if (args[0].type() != Types.ARRAY) {
throw new TypeException("Array expected in first argument");
}
final Value[] elements = ((ArrayValue) args[0]).getCopyElements();
switch (args.length) {
case 1:
Arrays.sort(elements);
break;
case 2:
if (args[1].type() != Types.FUNCTION) {
throw new TypeException("Function expected in second argument");
}
final Function comparator = ((FunctionValue) args[1]).getValue();
Arrays.sort(elements, (o1, o2) -> (int) comparator.execute(o1, o2).asNumber());
break;
default:
throw new ArgumentsMismatchException("Wrong number of arguments");
}
return new ArrayValue(elements);
}
}

View File

@ -13,6 +13,7 @@ public final class std implements Module {
public void init() { public void init() {
Functions.set("echo", new std_echo()); Functions.set("echo", new std_echo());
Functions.set("newarray", new std_newarray()); Functions.set("newarray", new std_newarray());
Functions.set("sort", new std_sort());
Functions.set("length", new std_length()); Functions.set("length", new std_length());
Functions.set("rand", new std_rand()); Functions.set("rand", new std_rand());
Functions.set("sleep", new std_sleep()); Functions.set("sleep", new std_sleep());