diff --git a/examples/forms/textarea.own b/examples/forms/textarea.own index 1d70efb..f659ff6 100644 --- a/examples/forms/textarea.own +++ b/examples/forms/textarea.own @@ -1,6 +1,6 @@ use ["std", "forms", "functional"] -text = join(map(range(1, 16), def(x) = "line " + x), "\n") +text = map(range(1, 16), def(x) = "line " + x).joinToString("\n") label = newLabel() textArea = newTextArea(text) textArea.addCaretListener(def(event) = updateInfo()) diff --git a/src/main/java/com/annimon/ownlang/lib/ArrayValue.java b/src/main/java/com/annimon/ownlang/lib/ArrayValue.java index d8935a1..bc824fb 100644 --- a/src/main/java/com/annimon/ownlang/lib/ArrayValue.java +++ b/src/main/java/com/annimon/ownlang/lib/ArrayValue.java @@ -1,5 +1,6 @@ package com.annimon.ownlang.lib; +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.exceptions.TypeException; import java.util.Arrays; import java.util.Iterator; @@ -48,6 +49,17 @@ public class ArrayValue implements Value, Iterable { return result; } + public static StringValue joinToString(ArrayValue array, String delimiter, String prefix, String suffix) { + final StringBuilder sb = new StringBuilder(); + for (Value value : array) { + if (sb.length() > 0) sb.append(delimiter); + else sb.append(prefix); + sb.append(value.asString()); + } + sb.append(suffix); + return new StringValue(sb.toString()); + } + private final Value[] elements; public ArrayValue(int size) { @@ -96,12 +108,30 @@ public class ArrayValue implements Value, Iterable { // Functions case "isEmpty": - return NumberValue.fromBoolean(size() == 0); + return Converters.voidToBoolean(() -> size() == 0); + case "joinToString": + return new FunctionValue(this::joinToString); default: return get(index.asInt()); } } + + public Value joinToString(Value[] args) { + Arguments.checkRange(0, 3, args.length); + switch (args.length) { + case 0: + return joinToString(this, "", "", ""); + case 1: + return joinToString(this, args[0].asString(), "", ""); + case 2: + return joinToString(this, args[0].asString(), args[1].asString(), args[1].asString()); + case 3: + return joinToString(this, args[0].asString(), args[1].asString(), args[2].asString()); + default: + throw new ArgumentsMismatchException("Wrong number of arguments"); + } + } public void set(int index, Value value) { elements[index] = value; diff --git a/src/main/java/com/annimon/ownlang/modules/functional/functional_stream.java b/src/main/java/com/annimon/ownlang/modules/functional/functional_stream.java index 05d5948..db6e8ca 100644 --- a/src/main/java/com/annimon/ownlang/modules/functional/functional_stream.java +++ b/src/main/java/com/annimon/ownlang/modules/functional/functional_stream.java @@ -8,7 +8,7 @@ import java.util.Arrays; public final class functional_stream implements Function { @Override - public Value execute(Value... args) { + public Value execute(Value[] args) { Arguments.checkAtLeast(1, args.length); if (args.length > 1) { @@ -52,10 +52,11 @@ public final class functional_stream implements Function { set("reduce", wrapTerminal(new functional_reduce())); set("forEach", wrapTerminal(new functional_foreach())); set("toArray", args -> container); + set("joining", container::joinToString); set("count", args -> NumberValue.of(container.size())); } - private Value skip(Value... args) { + private Value skip(Value[] args) { Arguments.check(1, args.length); final int skipCount = args[0].asInt(); @@ -71,7 +72,7 @@ public final class functional_stream implements Function { return new StreamValue(new ArrayValue(result)); } - private Value limit(Value... args) { + private Value limit(Value[] args) { Arguments.check(1, args.length); final int limitCount = args[0].asInt(); @@ -87,7 +88,7 @@ public final class functional_stream implements Function { return new StreamValue(new ArrayValue(result)); } - private Value sorted(Value... args) { + private Value sorted(Value[] args) { Arguments.checkOrOr(0, 1, args.length); final Value[] elements = container.getCopyElements(); @@ -106,7 +107,7 @@ public final class functional_stream implements Function { return new StreamValue(new ArrayValue(elements)); } - private Value custom(Value... args) { + private Value custom(Value[] args) { Arguments.check(1, args.length); final Function f = ValueUtils.consumeFunction(args[0], 0); final Value result = f.execute(container); @@ -115,7 +116,7 @@ public final class functional_stream implements Function { } return result; } - + private FunctionValue wrapIntermediate(Function f) { return wrap(f, true); } diff --git a/src/main/java/com/annimon/ownlang/modules/std/std_join.java b/src/main/java/com/annimon/ownlang/modules/std/std_join.java index 6bf417e..3696fb1 100644 --- a/src/main/java/com/annimon/ownlang/modules/std/std_join.java +++ b/src/main/java/com/annimon/ownlang/modules/std/std_join.java @@ -5,7 +5,6 @@ import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.lib.Arguments; import com.annimon.ownlang.lib.ArrayValue; import com.annimon.ownlang.lib.Function; -import com.annimon.ownlang.lib.StringValue; import com.annimon.ownlang.lib.Types; import com.annimon.ownlang.lib.Value; @@ -21,26 +20,15 @@ public final class std_join implements Function { final ArrayValue array = (ArrayValue) args[0]; switch (args.length) { case 1: - return join(array, "", "", ""); + return ArrayValue.joinToString(array, "", "", ""); case 2: - return join(array, args[1].asString(), "", ""); + return ArrayValue.joinToString(array, args[1].asString(), "", ""); case 3: - return join(array, args[1].asString(), args[2].asString(), args[2].asString()); + return ArrayValue.joinToString(array, args[1].asString(), args[2].asString(), args[2].asString()); case 4: - return join(array, args[1].asString(), args[2].asString(), args[3].asString()); + return ArrayValue.joinToString(array, args[1].asString(), args[2].asString(), args[3].asString()); default: throw new ArgumentsMismatchException("Wrong number of arguments"); } } - - private static StringValue join(ArrayValue array, String delimiter, String prefix, String suffix) { - final StringBuilder sb = new StringBuilder(); - for (Value value : array) { - if (sb.length() > 0) sb.append(delimiter); - else sb.append(prefix); - sb.append(value.asString()); - } - sb.append(suffix); - return new StringValue(sb.toString()); - } } diff --git a/src/test/resources/modules/functional/stream.own b/src/test/resources/modules/functional/stream.own index 6268143..b9478b0 100644 --- a/src/test/resources/modules/functional/stream.own +++ b/src/test/resources/modules/functional/stream.own @@ -43,6 +43,13 @@ def testCustom() { assertEquals([5,6,4,2], stream(data).custom(::reverse).toArray()) } +def testJoining() { + data = [1,2,3,4] + assertEquals("1234", stream(data).joining()) + assertEquals("1-2-3-4", stream(data).joining("-")) + assertEquals("<1-2-3-4>", stream(data).joining("-", "<", ">")) +} + def testPeek() { data = [2,3,4,5,6,7] expected = [2,4,6] diff --git a/src/test/resources/other/arrayFunctions.own b/src/test/resources/other/arrayFunctions.own index da25e6a..c16c1ed 100644 --- a/src/test/resources/other/arrayFunctions.own +++ b/src/test/resources/other/arrayFunctions.own @@ -22,5 +22,11 @@ def testGetLengthInnerArray() { def testIsEmpty() { arr = [1, 2, 3] - assertFalse(arr.isEmpty) + assertFalse(arr.isEmpty()) +} + +def testJoinToString() { + arr = [1, 2, 3] + assertEquals("123", arr.joinToString()) + assertEquals("1 2 3", arr.joinToString(" ")) } \ No newline at end of file