Sometimes backwards is best.
This is just a quick post on something I ran across for work and I though was interesting. I study Japanese and there is some research pointing to the fact that language can affect the way you think. I recently ran across a situation and wanted to discuss it briefly.
I was tasked with something quite simple. The problem was this: Take a list of strings and create an output that displays the list using natural english. The order of the output is inconsequential.
Example:
[“usagi”,“kitsune”] would producte the output: usagi and kitsune [“usagi”,“kitsune”,“kuma”] would product the output: usagi, kitsune and kuma. It also could produce kuma, kitsune and usagi. The order does not matter.
Let’s write a program:
Test Cases: I’ll write a quick table driven test here to check the empty list edge case and then a list with one, two, three and four strings. Since we will be working backwards the test needs to reflect that. Here is the test code:
naturalList_test.go
package main
import (
"testing"
)
func TestNaturalList(t *testing.T) {
var nlTests = []struct {
srcList []string
result string
}{
{[]string{""}, ""},
{[]string{"kitsune"}, "kitsune"},
{[]string{"kitsune", "usagi"}, "usagi and kitsune"},
{[]string{"kitsune", "usagi", "kuma"}, "kuma, usagi and kitsune"},
{[]string{"kitsune", "usagi", "kuma", "zou"}, "zou, kuma, usagi and kitsune"}}
for _, c := range nlTests {
nlRlt := NaturalList(c.srcList)
if c.result != NaturalList(c.srcList) {
t.Fatalf("Test Failed: Expected %s got %s", c.result, nlRlt)
}
}
}
Now let’s move on to the implementation:
naturalList.go
package naturalList
const (
primary_connector = ", "
final_connector = " and "
)
//NaturalList takes a list of strings and returns
//a syntactically correct ordered English list. The
//order of words does not matter.
func NaturalList(sl []string) (rlt string) {
for i, cs := range sl {
rlt = cs + rlt
if (i == 0) && (len(sl) > 1) {
rlt = final_connector + rlt
continue
}
if i != (len(sl) - 1) {
rlt = primary_connector + rlt
}
}
return
}
I suppose there could be another way to do this, but this way seemed simple and elegant. If you needed to preserve order, this algorithm would work but you would need a utility function to reverse the order of the input string list.
This was a neat excercise and I thought it would be nice to share.