"There is always a well-known solution to every human problem–neat, plausible, and wrong."
– H.L. Menken.
If you've ever gathered requirements, reviewed change requests, or even handled support tickets, you've probably seen cases where a proposed solution did not resolve the user's need. Learn to recognize the true need underlying a request so you can create solutions that actually solve problems.
To illustrate, consider the following book titles:
A Study in Scarlet The Sign of Four The Adventures of Sherlock Holmes The Memoirs of Sherlock Holmes The Hound of the Baskervilles The Return of Sherlock Holmes His Last Bow The Valley of Fear The Case-Book of Sherlock Holmes
Here, the writeTitle() function represents whatever display technique is appropriate for your use (example #1).
Your code might vary, but the underlying approach would likely be similar. You'd loop through the array and print each element value. (It's worth noting that the initial order roughly corresponds to original publication order of these titles.)
Now, suppose your users ask you to print the titles alphabetically. To do so, you might use (example #2):
This leads to:
A Study in Scarlet His Last Bow The Adventures of Sherlock Holmes The Case-Book of Sherlock Holmes The Hound of the Baskervilles The Memoirs of Sherlock Holmes The Return of Sherlock Holmes The Sign of Four The Valley of Fear
Sorting the values is the obvious, simplest answer. Is it the correct answer? Not really; it addresses the request, but not the need. This version uses the entire string value to determine sort order. However, there's a difference between alphabetic sorting and dictionary sorting (which ignores leading articles). In dictionary sorting, "A Study in Scarlet" appears after "The Sign of Four." The need, then, is to use dictionary sorting rather than strict alphabetic sorting.
In earlier times, libraries handled this by moving leading articles to the end of the title, as in "Study in Scarlet, A", "Sign of Four, The", and so on.
You could follow the same convention by modifying the data values accordingly:
"Adventures of Sherlock Holmes, The" "Case-Book of Sherlock Holmes, The" "His Last Bow" "Hound of the Baskervilles, The" "Memoirs of Sherlock Holmes, The" "Return of Sherlock Holmes, The" "Sign of Four, The" "Study in Scarlet, A" "Valley of Fear, The"
This approach is simple and leads to the expected result. It's well-known, neat, and plausible. It also avoids code changes. However, the technique forces the user to adapt to the limitations of the implementation. Worse, future features (such as search) become more difficult to implement. There must be a better way.
You might think to store separate data values: one displayed to the user and one used to sort the data. In the long run, this would be more effective than changing the data because it provides the correct order without affecting the user's experience. However, additional costs soon become apparent. First, storage increases because of the near duplicate data values. Second, your code now needs to synchronize both values when the data changes.
(Contrary to expectation, book titles can change over time. "The Sign of Four" was originally published as "The Sign of The Four" and there's an open debate as to which title is the correct one.)
Here, the moveLeadingArticle() function uses a regular expression to detect and move leading articles to the end of a title. The sorting code uses an anonymous function to override the built-in sort algorithm with one using the new function. These changes incorporate the librarian's trick without affecting the underlying data or the user's experience.
This provided the expected results:
The Adventures of Sherlock Holmes The Case-Book of Sherlock Holmes His Last Bow The Hound of the Baskervilles The Memoirs of Sherlock Holmes The Return of Sherlock Holmes The Sign of Four A Study in Scarlet The Valley of Fear
This solution meets the user's need without adversely affecting their experience, without requiring changes to the data, and without complicating future feature requests. This is the right answer.
Your users are unlikely to notice the additional effort put into your final solution. That's fine; it really is. The satisfaction of programming comes, in part, from correctly meeting user needs, even when the implementation needs a little more work than originally expected.
26 Jan 2017: Original post.