Добавлены функции 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)
println "flatmap"
foreach(nums, ::echo)
println "sort"
foreach(sort(nums, def(a,b) = b - a), ::echo)
use "http"

View File

@ -49,6 +49,12 @@ public final class ArrayValue implements Value, Iterable<Value> {
this(array.elements);
}
public Value[] getCopyElements() {
final Value[] result = new Value[elements.length];
System.arraycopy(elements, 0, result, 0, elements.length);
return result;
}
@Override
public int type() {
return Types.ARRAY;
@ -98,6 +104,15 @@ public final class ArrayValue implements Value, Iterable<Value> {
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
public String toString() {
return asString();

View File

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

View File

@ -51,7 +51,13 @@ public final class NumberValue implements 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
public String toString() {

View File

@ -54,6 +54,14 @@ public final class StringValue implements 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
public String toString() {
return asString();

View File

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

View File

@ -16,6 +16,7 @@ public final class functional implements Module {
Functions.set("flatmap", new functional_flatmap());
Functions.set("reduce", new functional_reduce());
Functions.set("filter", new functional_filter());
Functions.set("sortby", new functional_sortby());
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() {
Functions.set("echo", new std_echo());
Functions.set("newarray", new std_newarray());
Functions.set("sort", new std_sort());
Functions.set("length", new std_length());
Functions.set("rand", new std_rand());
Functions.set("sleep", new std_sleep());