Created
November 3, 2010 16:13
-
-
Save pingles/661278 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns tree | |
(:require [clojure.contrib.string :as str] | |
[clojure.contrib.io :as io])) | |
(defrecord Node [postcode region-id]) | |
(def lines (rest (io/read-lines "/Users/paul/Work/pes_db.csv"))) | |
(def postcodes-from-file (map (fn [x] (let [parts (str/split #"," x) | |
postcode (str/replace-str " " | |
"" | |
(first parts))] | |
(Node. postcode (second parts)))) | |
lines)) | |
(defn next-record | |
[record] | |
(Node. (apply str | |
(rest (:postcode record))) | |
(:region-id record))) | |
(defn record-to-tree | |
([record] (record-to-tree record {})) | |
([record tree] | |
(let [postcode (:postcode record)] | |
(if (nil? (seq postcode)) | |
{:region-id (:region-id record)} | |
(assoc tree | |
(keyword (str (first postcode))) | |
(record-to-tree (next-record record) | |
{})))))) | |
(defn merge-tree | |
[tree other] | |
(if (not (map? other)) | |
tree | |
(merge-with (fn [x y] (merge-tree x y)) | |
tree other))) | |
(def results (reduce merge-tree | |
{} | |
(map record-to-tree | |
postcodes-from-file))) | |
(defn lookup-postcode | |
[results postcode] | |
(if (nil? (seq postcode)) | |
(:region-id results) | |
(recur (results (keyword (str (first postcode)))) | |
(rest postcode)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try the code below that creates a map instead of a tree. It also avoids def'ing a top-level symbol like lines or postcodes-from-file, so those intermediate values need not be kept in memory at the end, and depending upon the version of Clojure you are using might even become garbage as soon as you advance past each element in the sequences.