aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/shedlang/compiler/util/Iterables.java
blob: 799c9c4f094576811cdd54e163f1d450698e0428 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package org.shedlang.compiler.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public class Iterables {
    private Iterables() {
    }

    public interface OnElement<T, E extends Exception> {
        void accept(T value) throws E;
    }

    public interface Between<E extends Exception> {
        void call() throws E;
    }

    public static <T, U> List<U> filterToType(Iterable<T> iterable, Class<U> clazz) {
        var result = new ArrayList<U>();

        for (var element : iterable) {
            if (clazz.isInstance(element)) {
                result.add(clazz.cast(element));
            }
        }

        return result;
    }

    public static <T> T first(Iterable<T> iterable) {
        return iterable.iterator().next();
    }

    public static <T, R> R foldLeft(
        R initial,
        Iterable<T> iterable,
        BiFunction<R, T, R> combine
    ) {
        R result = initial;

        for (var element : iterable) {
            result = combine.apply(result, element);
        }

        return result;
    }

    public static <T, E extends Exception> void forEachInterspersed(
        Iterable<T> values,
        OnElement<T, E> onElement,
        Between<E> between
    ) throws E {
        var first = true;
        for (var value : values) {
            if (!first) {
                between.call();
            }
            onElement.accept(value);
            first = false;
        }
    }

    public static <T, K extends Comparable<? super K>> List<T> sortedBy(
        Collection<T> collection,
        Function<? super T, ? extends K> key
    ) {
        return collection.stream().sorted(Comparator.comparing(key)).toList();
    }
}