Monday, April 13, 2009

Handle Multi-key to One-value Property File

One of my friend asked how to implement a configuration file which contains key to value mappings. One special thing is that multiple keys are mapped to one value. If Java property is used, the following text shows the property file.

# [v1]
K11=v1
K12=v1
K13=v1

# [v2]
K21=v2
K22=v2
K23=v2

# [v2]
K31=v3
K32=v3
K33=v3

It contains a lot of duplications. v1, v2 and v3 appears many times in the property file. DIY (Don't Repeat Yourself) principle is violated. One improvement is to write the following property file:

# [v1]
K11,K12,K13 = v1

# [v2]
K21, K22, K23 = v2

# [v2]
K31, K32, K33 = v3

For this property file, I need to write additional code. The following steps are one option:

  • get the entry set from the property file

  • create a hash map

  • iterate over the entry set. k is the map entry key, v is the map entry value


    • split the iterated k with , into key[]

    • add (key[0], v), (key[1], v), ... to the hash map



After the above steps done, the hash map can be used to get a value for a given key. There still one problem. The property file and the Java code are separated. Then I thought about Scheme. Here is the solution in Scheme. It is tested on DrScheme, version 4.1.4.

#lang scheme
(define (find-value k)
(let* ([ks2v '(

; multi-key to one-value mappings
((K11 K12 K13) V1)
((K21 K22 K23 K24) V2)
((K31 K32 K33 K34) V3)

)]
[contain? (lambda (k keys)
(let ([equal2k? (lambda (a) (equal? k a))])
(ormap equal2k? keys)))]
[k2v (lambda (pair)
(if (contain? k (car pair))
(cadr pair)
#f))])
(ormap k2v ks2v)))

This solution is elegant. Code as data characteristic of Scheme makes such kind of solutions possible. And when I was coding this solution, I had the same feeling as the quote SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.

No comments: