Pregunta

A menudo necesito ejecutar reducir (también llamado foldl / foldr, dependiendo de tus contextos) en java para agregar elementos de un Itterable.

Reducir toma una colección / iterable / etc, una función de dos parámetros y un valor de inicio opcional (dependiendo de los detalles de la implementación). La función se aplica sucesivamente a un elemento de la colección y la salida de la invocación anterior de reduce hasta que todos los elementos se hayan procesado y devuelva el valor final.

¿Existe una implementación segura de tipos de reducir en cualquier API de Java común? Colecciones de Google parece como si tuviera una, pero no he podido para encontrarlo. (posiblemente porque no sé qué otros nombres usaría).

¿Fue útil?

Solución

Probablemente puedas rodar tu propio genérico fácilmente, según tu descripción:

public interface Reducer<A, T>
{
    public A foldIn(A accum, T next);
}

Luego usando el patrón de estrategia:

public class Reductor<A, T>
{
    private Reducer<A, T> worker;
    public Reductor<A, T>(Reducer<A, T> worker)
    {
        this.worker = worker;
    }

    public A fold(A rval, Iterator<T> itr)
    {
        while(itr.hasNext())
        {
            A rval = worker.foldIn(rval, itr.next());
        }
        return rval;
    }
}

Estoy seguro de que hay un montón de errores de sintaxis, pero ese es el punto principal (hay algunas opciones que puede hacer sobre cómo obtener el valor del acumulador vacío. Luego, para usarlo en un iterador en particular, simplemente defina su Reductor en la volar:

Reductor r = new Reductor<A, T>(new Reducer<A, T>()
{
    public A foldIn(A prev, T next)
    {
        A rval;
       //do stuff...
       return rval;
     }
 }

 A fold = r.fold(new A(), collection.getIterator());

dependiendo de cómo funciona su iterador, esto puede plegarse hacia la izquierda o hacia la derecha siempre que el iterador vaya en la dirección correcta.

espero que esto ayude.

Otros consejos

Basado en la sugerencia de Luke, aquí hay una implementación legítima de Java:

public interface Reducer<A,T>
{
    A foldIn(A accum, T next);
}

public static <T> T reduce(final Reducer<T,T> reducer, 
        final Iterable<? extends T> i)
{
    T result = null;
    final Iterator<? extends T> iter = i.iterator();
    if (iter.hasNext())
    {
        result = iter.next();
        while (iter.hasNext())
        {
            result = reducer.foldIn(result, iter.next());
        }
    }
    return result;
}

public static <A,T> A reduce(final Reducer<A,T> reducer, 
        final Iterable<? extends T> i, 
        final A initializer)
{
    A result = initializer;
    final Iterator<? extends T> iter = i.iterator();
    while (iter.hasNext())
    {
        result = reducer.foldIn(result, iter.next());
    }
    return result;
}

Pruebe el paquete de funciones comunes commons . Ha estado en la caja de arena para siempre, pero creo que hará lo que quieras.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top