Reordering Delimited Data

When our town sends out bills, notices, and so on, we barcode the mail. By barcoding the mail, we get a postal discount. To be able to barcode the mail, we have to verify the address with USPS-approved address verification software.

We have implemented a method to validate addresses programmatically by sending each address to an IIS application. The application is implemented as a single ASP page which, upon session start-up, creates an Active/X object. That object allows the ASP page to communicate with AccuMail — http://www.smartsoftusa.com/accumail-frameworks.html — our address verification software.

The ASP page sends back data that looks like this.

APQT4|266 Broadway Apt 1||Soapville|ZA|99999-5311|APQT4|661|C011|

The pipe “|” characters are deliberately inserted by the ASP page to make http response data database insert ready.

Originally, I thought I would have to re-order this data. That turned out not to be the case. However,  I wound up writing this code to rearrange a sequence based on values in another.

First clojure.string/split turns the string into a sequence

(def in-vec (cstr/split "APQT4|266 Broadway Apt 1||Soapville|ZA|99999-5311|APQT4|661|C011|" #"|"))

["APQT4" "266 Broadway Apt 1" "" "Soapville" "ZA" "99999-5311" "APQT4" "661" "C011"]

Then we determine the reorder steps by creating a vector containing those steps, which would most like be a local let var.

(def in-vec-idx [0 1 2 3 4 5 7 8])

Finally, we call the function where in-seq is the sequence to be re-ordered, and in-seq-idxs is the sequence containing which contains the order of the re-arrangement of the original sequence.

(defn re-idx-seq
  "Takes a sequence -- in-seq -- and re-orders it using in-seq-indexes returning new-seq."
  [in-seq in-seq-idxs]
(reduce
  (fn [new-seq idx-val]
     (conj new-seq (nth in-seq idx-val)))
  []
  in-seq-idxs))

and get these results:

["APQT4" "266 Broadway Apt 1" "" "Soapville" "ZA" "99999-5311" "661" "C011"]

I played around with this to see if a map would do the trick, but reduce seemed to be the only way I could find to make this work.

Advertisements

3 Comments

Filed under Clojure

3 responses to “Reordering Delimited Data

  1. Assuming the address parts are stored in a vector, map can work too:

    (def parts ["APQT4" "266 Broadway Apt 1" "" "Soapville" "ZA" "99999-5311" "APQT4" "661" "C011"])
    (def idxs [0 1 2 3 4 5 7 8])
    (map parts idxs)
    => ("APQT4" "266 Broadway Apt 1" "" "Soapville" "ZA" "99999-5311" "661" "C011")
    • Indeed, and that technique’s so concise that in some cases it’d be worth forcing a seq into a vector just to be able to use it like that! In this particular use case, nth would soon become a burden if the seqs weren’t vectors.

  2. Here’s a variation:

    (def re-orderer (apply juxt (map #(fn [s] (nth s %)) in-vec-idx)))
    (re-orderer in-vec)
    => [“APQT4” “266 Broadway Apt 1” “” “Soapville” “ZA” “99999-5311” “661” “C011”]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s