Domanda

Ho spesso bisogno di eseguire ridurre (chiamato anche foldl / foldr, a seconda dei contesti) in Java per aggregare elementi di un itterabile.

Reduce accetta una raccolta / iterabile / etc, una funzione di due parametri e un valore iniziale facoltativo (a seconda dei dettagli di implementazione). La funzione viene successivamente applicata a un elemento della raccolta e l'output della precedente chiamata di ridurre fino a quando tutti gli elementi sono stati elaborati e restituisce il valore finale.

Esiste un'implementazione sicura di tipo di ridurre in qualsiasi API Java comune? Collezioni di Google sembra come dovrebbe averne uno, ma non sono stato in grado per trovarlo. (forse perché non so quali altri nomi userebbe.)

È stato utile?

Soluzione

probabilmente potresti lanciare il tuo generico abbastanza facilmente, in base alla tua descrizione:

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

Quindi utilizzando il modello di strategia:

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;
    }
}

Sono sicuro che ci sono un sacco di errori di sintassi ma questo è il punto principale (ci sono alcune scelte che potresti fare su come ottenere il valore dell'accumulatore vuoto. Quindi per usarlo su un particolare iteratore basta definire il tuo Riduttore sul fly:

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());

a seconda di come funziona il tuo iteratore, questo può piegare a sinistra o piegare a destra fintanto che l'iteratore va nella giusta direzione.

spero che questo aiuti.

Altri suggerimenti

Sulla base del suggerimento di Luke, ecco un'implementazione Java legittima:

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;
}

Prova il pacchetto di funzioni comuni . È stato nella sandbox per sempre, ma penso che farà quello che vuoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top