Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a list fold in Java

Tags:

I have a List and want to reduce it to a single value (functional programming term "fold", Ruby term inject), like

Arrays.asList("a", "b", "c") ... fold ... "a,b,c" 

As I am infected with functional programming ideas (Scala), I am looking for an easier/shorter way to code it than

sb = new StringBuilder for ... {   append ... } sb.toString 
like image 678
Peter Kofler Avatar asked Jun 04 '09 13:06

Peter Kofler


People also ask

What is folding in Java?

In functional programming, fold (also termed reduce, accumulate, aggregate, compress, or inject) refers to a family of higher-order functions that analyze a recursive data structure and through use of a given combining operation, recombine the results of recursively processing its constituent parts, building up a ...

What does list fold do?

fold starts folding the list by consecutively applying the folder function to elements in the list starting with the initial value and the first element. If the list is empty, the inital value is returned! The function List. sum is roughly List.

Is Java a functional language?

Java is a functional style language and the language like Haskell is a purely functional programming language. Let's understand a few concepts in functional programming: Higher-order functions: In functional programming, functions are to be considered as first-class citizens.


2 Answers

To answer your original question:

public static <A, B> A fold(F<A, F<B, A>> f, A z, Iterable<B> xs) { A p = z;   for (B x : xs)     p = f.f(p).f(x);   return p; } 

Where F looks like this:

public interface F<A, B> { public B f(A a); } 

As dfa suggested, Functional Java has this implemented, and more.

Example 1:

import fj.F; import static fj.data.List.list; import static fj.pre.Monoid.stringMonoid; import static fj.Function.flip; import static fj.Function.compose;  F<String, F<String, String>> sum = stringMonoid.sum(); String abc = list("a", "b", "c").foldLeft1(compose(sum, flip(sum).f(","))); 

Example 2:

import static fj.data.List.list; import static fj.pre.Monoid.stringMonoid; ... String abc = stringMonoid.join(list("a", "b", "c"), ","); 

Example 3:

import static fj.data.Stream.fromString; import static fj.data.Stream.asString; ... String abc = asString(fromString("abc").intersperse(',')); 
like image 151
Apocalisp Avatar answered Sep 17 '22 13:09

Apocalisp


Given

public static <T,Y> Y fold(Collection<? extends T> list, Injector<T,Y> filter){   for (T item : list){     filter.accept(item);   }   return filter.getResult(); }  public interface Injector<T,Y>{   public void accept(T item);   public Y getResult(); } 

Then usage just looks like

fold(myArray, new Injector<String,String>(){   private StringBuilder sb = new StringBuilder();   public void Accept(String item){ sb.append(item); }   public String getResult() { return sb.toString(); } } ); 
like image 38
Tetsujin no Oni Avatar answered Sep 18 '22 13:09

Tetsujin no Oni