Please wait. This can take some minutes ...
                    
                 
             
         
        
            
                
                    
                    
                        Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. 
                        
                        Project price only 1 $ 
                        
                            You can buy this project and download/modify it how often you want.
                        
                        
                        
                     
                 
             
         
             
    
    
    com.github.underscore.Underscore Maven / Gradle / Ivy 
    
/*
 * The MIT License (MIT)
 *
 * Copyright 2015-2024 Valentyn Kolesnikov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.github.underscore;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
/**
 * Underscore-java17 is a java port of Underscore.js.
 *
 * @author Valentyn Kolesnikov
 */
@SuppressWarnings({
    "java:S106",
    "java:S2095",
    "java:S2189",
    "java:S2272",
    "java:S2789",
    "java:S3740",
    "java:S5852"
})
public class Underscore {
    private static final Map> FUNCTIONS = new LinkedHashMap<>();
    private static final Map TEMPLATE_SETTINGS = new HashMap<>();
    private static final int MIN_PASSWORD_LENGTH_8 = 8;
    private static final long CAPACITY_SIZE_5 = 5L;
    private static final long CAPACITY_COEFF_2 = 2L;
    private static final long CAPACITY_SIZE_16 = 16L;
    private static final java.util.concurrent.atomic.AtomicInteger UNIQUE_ID =
            new java.util.concurrent.atomic.AtomicInteger(0);
    private static final String ALL_SYMBOLS = "([\\s\\S]+?)";
    private static final String EVALUATE = "evaluate";
    private static final String INTERPOLATE = "interpolate";
    private static final String ESCAPE = "escape";
    private static final String S_Q = "\\s*\\Q";
    private static final String E_S = "\\E\\s*";
    private static final java.util.regex.Pattern FORMAT_PATTERN =
            java.util.regex.Pattern.compile("\\{\\s*(\\d*)\\s*\\}");
    private static final Map ESCAPES = new HashMap<>();
    private final Iterable iterable;
    private final Optional string;
    static {
        TEMPLATE_SETTINGS.put(EVALUATE, "<%([\\s\\S]+?)%>");
        TEMPLATE_SETTINGS.put(INTERPOLATE, "<%=([\\s\\S]+?)%>");
        TEMPLATE_SETTINGS.put(ESCAPE, "<%-([\\s\\S]+?)%>");
        ESCAPES.put('&', "&");
        ESCAPES.put('<', "<");
        ESCAPES.put('>', ">");
        ESCAPES.put('"', """);
        ESCAPES.put('\'', "'");
        ESCAPES.put('`', "`");
    }
    public Underscore(final Iterable iterable) {
        this.iterable = iterable;
        this.string = Optional.empty();
    }
    public Underscore(final String string) {
        this.iterable = null;
        this.string = Optional.of(string);
    }
    private static void setTemplateKey(
            final Map templateSettings, final String key) {
        if (templateSettings.containsKey(key) && templateSettings.get(key).contains(ALL_SYMBOLS)) {
            TEMPLATE_SETTINGS.put(key, templateSettings.get(key));
        }
    }
    public static void templateSettings(final Map templateSettings) {
        setTemplateKey(templateSettings, EVALUATE);
        setTemplateKey(templateSettings, INTERPOLATE);
        setTemplateKey(templateSettings, ESCAPE);
    }
    private static final class WherePredicate implements Predicate {
        private final List> properties;
        private WherePredicate(List> properties) {
            this.properties = properties;
        }
        @Override
        public boolean test(final E elem) {
            for (Map.Entry prop : properties) {
                try {
                    if (!elem.getClass()
                            .getField(prop.getKey())
                            .get(elem)
                            .equals(prop.getValue())) {
                        return false;
                    }
                } catch (Exception ex) {
                    try {
                        if (!elem.getClass()
                                .getMethod(prop.getKey())
                                .invoke(elem)
                                .equals(prop.getValue())) {
                            return false;
                        }
                    } catch (Exception ignored) {
                        // ignored
                    }
                }
            }
            return true;
        }
    }
    private static final class TemplateImpl implements Template> {
        private final String template;
        private TemplateImpl(String template) {
            this.template = template;
        }
        @Override
        public String apply(Map value) {
            final String evaluate = TEMPLATE_SETTINGS.get(EVALUATE);
            final String interpolate = TEMPLATE_SETTINGS.get(INTERPOLATE);
            final String escape = TEMPLATE_SETTINGS.get(ESCAPE);
            String result = template;
            for (final Map.Entry element : value.entrySet()) {
                final String value1 =
                        String.valueOf(element.getValue())
                                .replace("\\", "\\\\")
                                .replace("$", "\\$");
                result =
                        java.util.regex.Pattern.compile(
                                        interpolate.replace(
                                                ALL_SYMBOLS, S_Q + element.getKey() + E_S))
                                .matcher(result)
                                .replaceAll(value1);
                result =
                        java.util.regex.Pattern.compile(
                                        escape.replace(ALL_SYMBOLS, S_Q + element.getKey() + E_S))
                                .matcher(result)
                                .replaceAll(escape(value1));
                result =
                        java.util.regex.Pattern.compile(
                                        evaluate.replace(ALL_SYMBOLS, S_Q + element.getKey() + E_S))
                                .matcher(result)
                                .replaceAll(value1);
            }
            return result;
        }
        @Override
        public List check(Map value) {
            final String evaluate = TEMPLATE_SETTINGS.get(EVALUATE);
            final String interpolate = TEMPLATE_SETTINGS.get(INTERPOLATE);
            final String escape = TEMPLATE_SETTINGS.get(ESCAPE);
            String result = template;
            final List notFound = new ArrayList<>();
            final List valueKeys = new ArrayList<>();
            for (final Map.Entry element : value.entrySet()) {
                final String key = "" + element.getKey();
                java.util.regex.Matcher matcher =
                        java.util.regex.Pattern.compile(
                                        interpolate.replace(ALL_SYMBOLS, S_Q + key + E_S))
                                .matcher(result);
                boolean isFound = matcher.find();
                result = matcher.replaceAll(String.valueOf(element.getValue()));
                matcher =
                        java.util.regex.Pattern.compile(
                                        escape.replace(ALL_SYMBOLS, S_Q + key + E_S))
                                .matcher(result);
                isFound |= matcher.find();
                result = matcher.replaceAll(escape(String.valueOf(element.getValue())));
                matcher =
                        java.util.regex.Pattern.compile(
                                        evaluate.replace(ALL_SYMBOLS, S_Q + key + E_S))
                                .matcher(result);
                isFound |= matcher.find();
                result = matcher.replaceAll(String.valueOf(element.getValue()));
                if (!isFound) {
                    notFound.add(key);
                }
                valueKeys.add(key);
            }
            final List templateVars = new ArrayList<>();
            java.util.regex.Matcher matcher =
                    java.util.regex.Pattern.compile(interpolate).matcher(result);
            while (matcher.find()) {
                templateVars.add(matcher.group(1).trim());
            }
            result = matcher.replaceAll("");
            matcher = java.util.regex.Pattern.compile(escape).matcher(result);
            while (matcher.find()) {
                templateVars.add(matcher.group(1).trim());
            }
            result = matcher.replaceAll("");
            matcher = java.util.regex.Pattern.compile(evaluate).matcher(result);
            while (matcher.find()) {
                templateVars.add(matcher.group(1).trim());
            }
            notFound.addAll(difference(templateVars, valueKeys));
            return notFound;
        }
    }
    private static final class MyIterable implements Iterable {
        private final UnaryOperator unaryOperator;
        private boolean firstRun = true;
        private T value;
        MyIterable(final T seed, final UnaryOperator unaryOperator) {
            this.value = seed;
            this.unaryOperator = unaryOperator;
        }
        public Iterator iterator() {
            return new Iterator<>() {
                @Override
                public boolean hasNext() {
                    return true;
                }
                @Override
                public T next() {
                    if (firstRun) {
                        firstRun = false;
                    } else {
                        value = unaryOperator.apply(value);
                    }
                    return value;
                }
                @Override
                public void remove() {
                    // ignored
                }
            };
        }
    }
    public static  Function, V> iteratee(final K key) {
        return item -> item.get(key);
    }
    /*
     * Documented, #each
     */
    public static  void each(final Iterable iterable, final Consumer super T> func) {
        for (T element : iterable) {
            func.accept(element);
        }
    }
    public static  void eachIndexed(
            final Iterable iterable, final BiConsumer func) {
        int index = 0;
        for (T element : iterable) {
            func.accept(index, element);
            index += 1;
        }
    }
    public void each(final Consumer super T> func) {
        each(iterable, func);
    }
    public static  void eachRight(final Iterable iterable, final Consumer super T> func) {
        each(reverse(iterable), func);
    }
    public void eachRight(final Consumer super T> func) {
        eachRight(iterable, func);
    }
    public static  void forEach(final Iterable iterable, final Consumer super T> func) {
        each(iterable, func);
    }
    public static  void forEachIndexed(
            final Iterable iterable, final BiConsumer func) {
        eachIndexed(iterable, func);
    }
    public void forEach(final Consumer super T> func) {
        each(iterable, func);
    }
    public void forEachIndexed(final BiConsumer func) {
        eachIndexed(iterable, func);
    }
    public static  void forEachRight(
            final Iterable iterable, final Consumer super T> func) {
        eachRight(iterable, func);
    }
    public void forEachRight(final Consumer super T> func) {
        eachRight(iterable, func);
    }
    /*
     * Documented, #map
     */
    public static  List map(final List list, final Function super E, T> func) {
        final List transformed = newArrayListWithExpectedSize(list.size());
        for (E element : list) {
            transformed.add(func.apply(element));
        }
        return transformed;
    }
    public static  List mapMulti(
            final List list, final BiConsumer super E, ? super Consumer> mapper) {
        final List transformed = newArrayListWithExpectedSize(list.size());
        for (E element : list) {
            Consumer value = transformed::add;
            mapper.accept(element, value);
        }
        return transformed;
    }
    public  List map(final Function super T, F> func) {
        return map(newArrayList(iterable), func);
    }
    public static  List map(final int[] array, final Function super Integer, T> func) {
        final List transformed = newArrayListWithExpectedSize(array.length);
        for (int element : array) {
            transformed.add(func.apply(element));
        }
        return transformed;
    }
    public static  Set map(final Set set, final Function super E, T> func) {
        final Set transformed = newLinkedHashSetWithExpectedSize(set.size());
        for (E element : set) {
            transformed.add(func.apply(element));
        }
        return transformed;
    }
    public static  List mapIndexed(
            final List list, final BiFunction func) {
        final List transformed = newArrayListWithExpectedSize(list.size());
        int index = 0;
        for (E element : list) {
            transformed.add(func.apply(index, element));
            index += 1;
        }
        return transformed;
    }
    public static  List replace(
            final Iterable iter, final Predicate pred, final T value) {
        List list = newArrayList(iter);
        if (pred == null) {
            return list;
        }
        ListIterator itera = list.listIterator();
        while (itera.hasNext()) {
            if (pred.test(itera.next())) {
                itera.set(value);
            }
        }
        return list;
    }
    public List replace(final Predicate pred, final T value) {
        return replace(value(), pred, value);
    }
    public static  List replaceIndexed(
            final Iterable iter, final PredicateIndexed pred, final T value) {
        List list = newArrayList(iter);
        if (pred == null) {
            return list;
        }
        ListIterator itera = list.listIterator();
        int index = 0;
        while (itera.hasNext()) {
            if (pred.test(index, itera.next())) {
                itera.set(value);
            }
            index++;
        }
        return list;
    }
    public List replaceIndexed(final PredicateIndexed pred, final T value) {
        return replaceIndexed(value(), pred, value);
    }
    public  List mapIndexed(final BiFunction func) {
        return mapIndexed(newArrayList(iterable), func);
    }
    public static  List collect(final List list, final Function super E, T> func) {
        return map(list, func);
    }
    public static  Set collect(final Set set, final Function super E, T> func) {
        return map(set, func);
    }
    /*
     * Documented, #reduce
     */
    public static  E reduce(
            final Iterable iterable, final BiFunction func, final E zeroElem) {
        E accum = zeroElem;
        for (T element : iterable) {
            accum = func.apply(accum, element);
        }
        return accum;
    }
    public static  Optional reduce(final Iterable iterable, final BinaryOperator func) {
        boolean foundAny = false;
        T accum = null;
        for (T element : iterable) {
            if (foundAny) {
                accum = func.apply(accum, element);
            } else {
                foundAny = true;
                accum = element;
            }
        }
        return foundAny ? Optional.of(accum) : Optional.empty();
    }
    public static  E reduce(
            final int[] array, final BiFunction func, final E zeroElem) {
        E accum = zeroElem;
        for (int element : array) {
            accum = func.apply(accum, element);
        }
        return accum;
    }
    public static  E reduce(
            final T[] array, final BiFunction func, final E zeroElem) {
        E accum = zeroElem;
        for (T element : array) {
            accum = func.apply(accum, element);
        }
        return accum;
    }
    public static  E foldl(
            final Iterable iterable, final BiFunction func, final E zeroElem) {
        return reduce(iterable, func, zeroElem);
    }
    public static  E inject(
            final Iterable iterable, final BiFunction func, final E zeroElem) {
        return reduce(iterable, func, zeroElem);
    }
    /*
     * Documented, #reduceRight
     */
    public static  E reduceRight(
            final Iterable iterable, final BiFunction func, final E zeroElem) {
        return reduce(reverse(iterable), func, zeroElem);
    }
    public static  Optional reduceRight(
            final Iterable iterable, final BinaryOperator func) {
        return reduce(reverse(iterable), func);
    }
    public static  E reduceRight(
            final int[] array, final BiFunction func, final E zeroElem) {
        E accum = zeroElem;
        for (Integer element : reverse(array)) {
            accum = func.apply(accum, element);
        }
        return accum;
    }
    public static  E reduceRight(
            final T[] array, final BiFunction func, final E zeroElem) {
        return reduce(reverse(array), func, zeroElem);
    }
    public static  E foldr(
            final Iterable iterable, final BiFunction func, final E zeroElem) {
        return reduceRight(iterable, func, zeroElem);
    }
    /*
     * Documented, #find
     */
    public static  Optional find(final Iterable iterable, final Predicate pred) {
        for (E element : iterable) {
            if (pred.test(element)) {
                return isNull(element) ? null : Optional.of(element);
            }
        }
        return Optional.empty();
    }
    public static  Optional detect(final Iterable iterable, final Predicate pred) {
        return find(iterable, pred);
    }
    public static  Optional findLast(final Iterable iterable, final Predicate pred) {
        return find(reverse(iterable), pred);
    }
    /*
     * Documented, #filter
     */
    public static  List filter(final Iterable iterable, final Predicate pred) {
        final List filtered = new ArrayList<>();
        for (E element : iterable) {
            if (pred.test(element)) {
                filtered.add(element);
            }
        }
        return filtered;
    }
    public static  List filter(final List list, final Predicate pred) {
        final List filtered = new ArrayList<>();
        for (E element : list) {
            if (pred.test(element)) {
                filtered.add(element);
            }
        }
        return filtered;
    }
    public List filter(final Predicate pred) {
        final List filtered = new ArrayList<>();
        for (final T element : value()) {
            if (pred.test(element)) {
                filtered.add(element);
            }
        }
        return filtered;
    }
    public static  List filterIndexed(final List list, final PredicateIndexed pred) {
        final List filtered = new ArrayList<>();
        int index = 0;
        for (E element : list) {
            if (pred.test(index, element)) {
                filtered.add(element);
            }
            index += 1;
        }
        return filtered;
    }
    public static  Set filter(final Set set, final Predicate pred) {
        final Set filtered = new LinkedHashSet<>();
        for (E element : set) {
            if (pred.test(element)) {
                filtered.add(element);
            }
        }
        return filtered;
    }
    public static  List select(final List list, final Predicate pred) {
        return filter(list, pred);
    }
    public static  Set select(final Set set, final Predicate pred) {
        return filter(set, pred);
    }
    /*
     * Documented, #reject
     */
    public static  List reject(final List list, final Predicate pred) {
        return filter(list, input -> !pred.test(input));
    }
    public List reject(final Predicate pred) {
        return filter(input -> !pred.test(input));
    }
    public static  List rejectIndexed(final List list, final PredicateIndexed pred) {
        return filterIndexed(list, (index, input) -> !pred.test(index, input));
    }
    public static  Set reject(final Set set, final Predicate pred) {
        return filter(set, input -> !pred.test(input));
    }
    public static  List filterFalse(final List list, final Predicate pred) {
        return reject(list, pred);
    }
    public List filterFalse(final Predicate pred) {
        return reject(pred);
    }
    public static  Set filterFalse(final Set set, final Predicate pred) {
        return reject(set, pred);
    }
    public static  boolean every(final Iterable iterable, final Predicate pred) {
        for (E item : iterable) {
            if (!pred.test(item)) {
                return false;
            }
        }
        return true;
    }
    public boolean every(final Predicate pred) {
        return every(iterable, pred);
    }
    /*
     * Documented, #all
     */
    public static  boolean all(final Iterable iterable, final Predicate pred) {
        return every(iterable, pred);
    }
    public boolean all(final Predicate pred) {
        return every(iterable, pred);
    }
    public static  boolean some(final Iterable iterable, final Predicate pred) {
        Optional optional = find(iterable, pred);
        return optional == null || optional.isPresent();
    }
    public boolean some(final Predicate pred) {
        return some(iterable, pred);
    }
    /*
     * Documented, #any
     */
    public static  boolean any(final Iterable iterable, final Predicate pred) {
        return some(iterable, pred);
    }
    public boolean any(final Predicate pred) {
        return some(iterable, pred);
    }
    public static  int count(final Iterable iterable, final Predicate pred) {
        int result = 0;
        for (E item : iterable) {
            if (pred.test(item)) {
                result += 1;
            }
        }
        return result;
    }
    public int count(final Predicate pred) {
        return count(iterable, pred);
    }
    public static  boolean contains(final Iterable iterable, final E elem) {
        return some(iterable, e -> Objects.equals(elem, e));
    }
    public boolean contains(final T elem) {
        return contains(iterable, elem);
    }
    public static  boolean containsWith(final Iterable iterable, final E elem) {
        return some(
                iterable,
                e -> elem == null ? e == null : String.valueOf(e).contains(String.valueOf(elem)));
    }
    public boolean containsWith(final T elem) {
        return containsWith(iterable, elem);
    }
    public static  boolean contains(
            final Iterable iterable, final E elem, final int fromIndex) {
        final List list = newArrayList(iterable);
        return contains(list.subList(fromIndex, list.size()), elem);
    }
    public boolean containsAtLeast(final T value, final int count) {
        return Underscore.containsAtLeast(this.iterable, value, count);
    }
    public boolean containsAtMost(final T value, final int count) {
        return Underscore.containsAtMost(this.iterable, value, count);
    }
    public static  boolean containsAtLeast(
            final Iterable iterable, final E value, final int count) {
        int foundItems = 0;
        for (E element : iterable) {
            if (Objects.equals(element, value)) {
                foundItems += 1;
            }
            if (foundItems >= count) {
                break;
            }
        }
        return foundItems >= count;
    }
    public static  boolean containsAtMost(
            final Iterable iterable, final E value, final int count) {
        int foundItems = size(iterable);
        for (E element : iterable) {
            if (!(Objects.equals(element, value))) {
                foundItems -= 1;
            }
            if (foundItems <= count) {
                break;
            }
        }
        return foundItems <= count;
    }
    /*
     * Documented, #include
     */
    public static  boolean include(final Iterable iterable, final E elem) {
        return contains(iterable, elem);
    }
    /*
     * Documented, #invoke
     */
    @SuppressWarnings("unchecked")
    public static  List invoke(
            final Iterable iterable, final String methodName, final List args) {
        final List result = new ArrayList<>();
        final List> argTypes = map(args, Object::getClass);
        try {
            final Method method =
                    iterable.iterator()
                            .next()
                            .getClass()
                            .getMethod(methodName, argTypes.toArray(new Class[0]));
            for (E arg : iterable) {
                doInvoke(args, result, method, arg);
            }
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException(e);
        }
        return result;
    }
    @SuppressWarnings("unchecked")
    private static  void doInvoke(List args, List result, Method method, E arg) {
        try {
            result.add((E) method.invoke(arg, args.toArray(new Object[0])));
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
    public List invoke(final String methodName, final List args) {
        return invoke(iterable, methodName, args);
    }
    public static  List invoke(final Iterable iterable, final String methodName) {
        return invoke(iterable, methodName, Collections.emptyList());
    }
    public List invoke(final String methodName) {
        return invoke(iterable, methodName);
    }
    /*
     * Documented, #pluck
     */
    public static  List pluck(final List list, final String propertyName) {
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        return map(
                list,
                elem -> {
                    try {
                        return elem.getClass().getField(propertyName).get(elem);
                    } catch (Exception e) {
                        try {
                            return elem.getClass().getMethod(propertyName).invoke(elem);
                        } catch (Exception ex) {
                            throw new IllegalArgumentException(ex);
                        }
                    }
                });
    }
    public List pluck(final String propertyName) {
        return pluck(newArrayList(iterable), propertyName);
    }
    public static  Set pluck(final Set set, final String propertyName) {
        if (set.isEmpty()) {
            return Collections.emptySet();
        }
        return map(
                set,
                elem -> {
                    try {
                        return elem.getClass().getField(propertyName).get(elem);
                    } catch (Exception e) {
                        try {
                            return elem.getClass().getMethod(propertyName).invoke(elem);
                        } catch (Exception ex) {
                            throw new IllegalArgumentException(ex);
                        }
                    }
                });
    }
    /*
     * Documented, #where
     */
    public static  List