7

Itterable の要素を集約するために Java で reduce (コンテキストによっては foldl / foldr とも呼ばれます) を実行する必要があることがよくあります。

Reduce は collection/iterable/etc、2 つのパラメーターの関数、およびオプションの開始値 (実装の詳細に応じて) を取ります。この関数は、すべての要素が処理されるまで、コレクションの要素と前回の reduce 呼び出しの出力に連続して適用され、最終的な値を返します。

一般的なJava APIにreduceのタイプセーフな実装はありますか? Google Collectionsに 1 つあるはずですが、見つかりませんでした。(おそらく、他の名前を使用するかわからないためです。)

4

3 に答える 3

2

Lukeの提案に基づいて、ここに正当な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;
}
于 2010-06-21T20:45:21.630 に答える
2

あなたの説明に基づいて、おそらくあなた自身のジェネリックをかなり簡単に転がすことができます:

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

次に、戦略パターンを使用します。

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

大量の構文エラーがあると確信していますが、それが主なポイントです (空のアキュムレータ値を取得する方法についていくつかの選択肢があります。次に、特定のイテレータでそれを使用するには、その場で Reducer を定義するだけです。

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

イテレータがどのように機能するかに応じて、イテレータが右方向に進む限り、左または右に折りたたむことができます。

お役に立てれば。

于 2008-10-21T19:26:24.177 に答える
1

commons functor パッケージを試してください。それはずっとサンドボックスにありましたが、あなたが望むことをすると思います.

于 2008-10-21T18:59:15.870 に答える