Hi!

I started to look closer at Clojure after Rich Hickey's presentation
at QCon London in March, this is my first post. I spend my days
programming Java, but my journey as developer did actually start with
an ML programming course many years ago. It has been great fun to
re-discover the functional style of programming again! This list is a
great source of knowledge.

A colleague of mine wrote an article about how to convert a piece of
Java code to Groovy a few months ago. As an exercise I thought I
should do the same, but to Clojure of course. I'd really appreciate
some feedback on the solution. I hope you aren't too sick of these
kind of posts just yet :-)

The code orders a list of characters, first by frequency and then
alphabetically if two characters happen to have the same frequency.

A Java unit test:

private void doTestOrderByFreq(Orderer orderer) {
        List<String> unordered = Arrays.asList("b", "d", "b", "b",
"a", "c", "a");
        List<String> ordered = orderer.orderByFreq(unordered);
        assertEquals(Arrays.asList("b", "a", "c", "d"), ordered);
}

A Java implementation:

public class JavaOrderer implements Orderer {

    public List<String> orderByFreq(List<String> in) {
        final Bag bag = new HashBag(in);
        List<String> out = new ArrayList<String>(bag.uniqueSet());

        Collections.sort(out, new Comparator<String>() {
            public int compare(String a, String b) {
                int freq = Integer.valueOf(
                    bag.getCount(b)).compareTo(bag.getCount(a)
                );
                return freq != 0 ? freq : a.compareTo(b);
            }
        });

        return out;
    }
}

My shot at a Clojure implementation, with inspiration from a previous
post in this group on a similar problem:

(ns step3.pnehm.clojure-orderer
  (:gen-class
    :name step3.pnehm.ClojureOrderer
    :implements [pnehm.Orderer]
    ))

(defn count-words [coll]
  (reduce #(merge-with + %1 {%2 1}) {} coll))

(defn cmpr [[val1 freq1] [val2 freq2]]
  (let [freq (compare freq2 freq1)]
    (if (not= freq 0) freq (compare val1 val2))))

(defn -orderByFreq [_ coll]
  (if (empty? coll) () (keys (sort cmpr (count-words coll)))))

Orderer is a simple Java interface making it easy to call different
implementations from the JUnit test:

List<String> orderByFreq(List<String> in);

All kinds of feedback are welcome, both on style and the chosen solution.

Many thanks!

/Patrik

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to