mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
[functional] Move indexed variant of Stream.forEach to Stream,forEachIndexed
This commit is contained in:
parent
d643f596a8
commit
2bb5e45517
@ -30,6 +30,7 @@ class StreamValue extends MapValue {
|
|||||||
|
|
||||||
set("reduce", wrapTerminal(new functional_reduce()));
|
set("reduce", wrapTerminal(new functional_reduce()));
|
||||||
set("forEach", wrapTerminal(new functional_forEach()));
|
set("forEach", wrapTerminal(new functional_forEach()));
|
||||||
|
set("forEachIndexed", wrapTerminal(new functional_forEachIndexed()));
|
||||||
set("toArray", args -> container);
|
set("toArray", args -> container);
|
||||||
set("joining", container::joinToString);
|
set("joining", container::joinToString);
|
||||||
set("count", args -> NumberValue.of(container.size()));
|
set("count", args -> NumberValue.of(container.size()));
|
||||||
|
@ -15,17 +15,16 @@ public final class functional_forEach implements Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Value forEach(Value container, Function consumer) {
|
static Value forEach(Value container, Function consumer) {
|
||||||
final int argsCount = consumer.getArgsCount();
|
|
||||||
return switch (container.type()) {
|
return switch (container.type()) {
|
||||||
case Types.STRING -> forEachString((StringValue) container, argsCount, consumer);
|
case Types.STRING -> forEachString((StringValue) container, consumer);
|
||||||
case Types.ARRAY -> forEachArray((ArrayValue) container, argsCount, consumer);
|
case Types.ARRAY -> forEachArray((ArrayValue) container, consumer);
|
||||||
case Types.MAP -> forEachMap((MapValue) container, consumer);
|
case Types.MAP -> forEachMap((MapValue) container, consumer);
|
||||||
default -> throw new TypeException("Cannot iterate " + Types.typeToString(container.type()));
|
default -> throw new TypeException("Cannot iterate " + Types.typeToString(container.type()));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringValue forEachString(StringValue string, int argsCount, Function consumer) {
|
static StringValue forEachString(StringValue string, Function consumer) {
|
||||||
if (argsCount == 2) {
|
if (consumer.getArgsCount() == 2) {
|
||||||
for (char ch : string.asString().toCharArray()) {
|
for (char ch : string.asString().toCharArray()) {
|
||||||
consumer.execute(new StringValue(String.valueOf(ch)), NumberValue.of(ch));
|
consumer.execute(new StringValue(String.valueOf(ch)), NumberValue.of(ch));
|
||||||
}
|
}
|
||||||
@ -37,17 +36,10 @@ public final class functional_forEach implements Function {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayValue forEachArray(ArrayValue array, int argsCount, Function consumer) {
|
static ArrayValue forEachArray(ArrayValue array, Function consumer) {
|
||||||
if (argsCount == 2) {
|
|
||||||
int index = 0;
|
|
||||||
for (Value element : array) {
|
|
||||||
consumer.execute(element, NumberValue.of(index++));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (Value element : array) {
|
for (Value element : array) {
|
||||||
consumer.execute(element);
|
consumer.execute(element);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.annimon.ownlang.modules.functional;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.*;
|
||||||
|
|
||||||
|
public final class functional_forEachIndexed implements Function {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value execute(Value[] args) {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
final Value container = args[0];
|
||||||
|
final Function consumer = ValueUtils.consumeFunction(args[1], 1);
|
||||||
|
return forEachIndexed(container, consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value forEachIndexed(Value container, Function consumer) {
|
||||||
|
if (container.type() == Types.ARRAY) {
|
||||||
|
return forEachIndexedArray((ArrayValue) container, consumer);
|
||||||
|
}
|
||||||
|
// Only used in Streams -> no Map implementation
|
||||||
|
throw new TypeException("Cannot iterate " + Types.typeToString(container.type()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ArrayValue forEachIndexedArray(ArrayValue array, Function consumer) {
|
||||||
|
int index = 0;
|
||||||
|
for (Value element : array) {
|
||||||
|
consumer.execute(element, NumberValue.of(index++));
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use std, functional
|
use std, functional
|
||||||
|
|
||||||
def testArrayForeach1Arg() {
|
def testArrayForeachArg() {
|
||||||
sum = 0
|
sum = 0
|
||||||
foreach([1, 2, 3], def(v) {
|
foreach([1, 2, 3], def(v) {
|
||||||
sum += v
|
sum += v
|
||||||
@ -8,14 +8,6 @@ def testArrayForeach1Arg() {
|
|||||||
assertEquals(6, sum)
|
assertEquals(6, sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
def testArrayForeach2Args() {
|
|
||||||
sum = 0
|
|
||||||
foreach([1, 2, 3], def(v, index) {
|
|
||||||
sum += v * index
|
|
||||||
})
|
|
||||||
assertEquals(1 * 0 + 2 * 1 + 3 * 2, sum)
|
|
||||||
}
|
|
||||||
|
|
||||||
def testStringForeach1Arg() {
|
def testStringForeach1Arg() {
|
||||||
sum = 0
|
sum = 0
|
||||||
foreach("abcd", def(s) {
|
foreach("abcd", def(s) {
|
||||||
|
@ -79,6 +79,28 @@ def testSorted() {
|
|||||||
assertEquals([-2,3,4,-5,6,6,-8], stream(data).sorted(def(a,b) = abs(a) - abs(b)).toArray())
|
assertEquals([-2,3,4,-5,6,6,-8], stream(data).sorted(def(a,b) = abs(a) - abs(b)).toArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def testForEachArrayIndexed() {
|
||||||
|
data = [1, 2, 3]
|
||||||
|
sum = 0
|
||||||
|
stream(data)
|
||||||
|
.forEachIndexed(def(v, index) {
|
||||||
|
sum += (v * index)
|
||||||
|
})
|
||||||
|
assertEquals(1 * 0 + 2 * 1 + 3 * 2, sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
def testForEachMapIndexed() {
|
||||||
|
data = {"a": "1", "b": 2}
|
||||||
|
result = ""
|
||||||
|
stream(data)
|
||||||
|
.sorted()
|
||||||
|
.forEachIndexed(def(entry, index) {
|
||||||
|
extract(key, value) = entry
|
||||||
|
result += "" + key + value + index
|
||||||
|
})
|
||||||
|
assertEquals("a10b21", result)
|
||||||
|
}
|
||||||
|
|
||||||
def reverse(container) {
|
def reverse(container) {
|
||||||
size = length(container)
|
size = length(container)
|
||||||
result = newarray(size)
|
result = newarray(size)
|
||||||
|
Loading…
Reference in New Issue
Block a user