Design a map for name generation

Imagine you are writing a simple name generator that takes your name and creates an alternative version. For example this could be a generator of your “Posh” or “Hipster” name.

Note Define a data structure to model sloane names that has three names for every letter of the alphabet. For name suggestions, see the Tattler sloane name generator.

The following seems to be the simplest way to model the sloane names. This follows the representation in the original source material.

  1. (def sloane-first-name
  2. {"a" "Ally-Pally"
  3. "b" "Bongo"
  4. "c" "Chipper"})
  5. (def slone-second-name
  6. {"a" "Anstruther"
  7. "b" "Beaufort"
  8. "c" "Cholmondeley"})
  9. (def slone-third-name
  10. {"a" "Arbuthnot"
  11. "b" "Battenburg"
  12. "c" "Coutts"})

The following alternative data structure design is very simple and more consise, however it does loose some of the semantic meaning. The position of the names is not defined in terms of the contenxt of the problem.

  1. (def slone-names
  2. {:a ["Ally-Pally" "Anstruther" "Arbuthnot"]})

This next design removes some of the redundancy in defining each letter of the alphabet several times. Apart from less typing and therefore reading by the development teeam, it also explicitly defines the semantic meaning of each name within the context of this problem.

  1. (def slone-names
  2. {:a {:first "Ally-Pally" :second "Anstruther" :third "Arbuthnot"}})

For extra points you could try and implement a function that generated your sloane name.

Creating the algorithm to construct your sloane name

  • The first sloane name is chosen from the first character of the first name
  • The second sloane name chosen from the first character of the second name
  • The third sloane name is chosen from the second character of the second name

You can get the first element of a string by treating it just like a collection. However this returns a character

  1. (first "Strings also act as collections")

A string can be converted to a keyword, a character cannot

  1. (keyword "a")

A character can be converted to a string using the str function

  1. (str (first "Strings also act as collections"))

The keywords need to be the same case, so convert the first character to lower case (which returns a string, so the explicit str function is no longer required.)

  1. (clojure.string/lower-case (first "Strings also act as collections"))

Putting it all together.

  1. (keyword (clojure.string/lower-case (first "Strings also act as collections")))

Create a function to calculate your sloane name

Putting all this together in a function to generate your sloan name, given your a string with your first and last name.

  1. (defn sloane-name
  2. "Given a first and last name as a string, returns your equivalent Sloane name as a string"
  3. [name]
  4. (let [first-name (keyword (clojure.string/lower-case (first (first (clojure.string/split name #" ")))))
  5. middle-name (keyword (clojure.string/lower-case (first (second (clojure.string/split name #" ")))))
  6. last-name (keyword (clojure.string/lower-case (second (second (clojure.string/split name #" ")))))]
  7. (str (get-in slone-names [first-name :first])
  8. " "
  9. (get-in slone-names [middle-name :second])
  10. " "
  11. (get-in slone-names [last-name :third]))))

Supply a name that will test if the sloane-name function works

  1. (sloane-name "Billy Abstainer")
  2. ;; => "Bongo Anstruther Battenburg"