HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptMinor

There Was an Old Lady - generate lyrics to a cumulation song

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
ladygeneratecumulationlyricssongwasthereold

Problem

This is a problem from exercism.io. View the repo here (contains full example of song).

Problem statement:

Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.

While you could copy/paste the lyrics,
or read them from a file, this problem is much more
interesting if you approach it algorithmically.

This problem is quite similar to my previous question of 99 bottles. I've adopted what I learned from that review with the goal of writing idiomatic javascript and clean code.

Being new to javascript, I'm wondering if anything sticks out that might be improved.

food-chain.js

``
const FoodChain = module.exports = {
FOOD_CHAIN: {
'fly': "",
'spider': "It wriggled and jiggled and tickled inside her.\n",
'bird': "How absurd to swallow a bird!\n",
'cat': "Imagine that, to swallow a cat!\n",
'dog': "What a hog, to swallow a dog!\n",
'goat': "Just opened her throat and swallowed a goat!\n",
'cow': "I don't know how she swallowed a cow!\n",
'horse': "She's dead, of course!\n",
},

getKeyAtIndex(index) {
return Object.keys(this.FOOD_CHAIN)[index];
},

getVerseAtKey(key) {
return this.FOOD_CHAIN[key];
},

verse(number) {
const food = Food.getFood(number - 1);

return (
I know an old lady who swallowed a ${food.name}.\n +
${food.verse} +
${this.getRepeatedVerses(food.rank)}`
);
},

getRepeatedVerses(rank) {
return [...this.reciteRepeatedVerses(rank)].join('\n');
},

*reciteRepeatedVerses(rank) {
let current = rank;

while (current >= 0) {
const food = Food.getFood(current--);
if (food.name === 'horse') break;
yield food.repeatedVerse;
}
},

verses(...range) {
this.validateArguments(...range);
return [...this.reciteRangeOfVerses(...range)].join('\n') + '\n';
},

*reciteRangeOfVerses(starting, ending = 0) {
let current = starting;

while (current arg 2) {
throw new RangeError('Invalid arguments:

Solution

Feedback

Nice work using the classes and sub-classes, as well as generators and the keywords const and let where appropriate
Suggestions
Sub-class constructors identical to super constructor

The sub-class constructors (for Fly and Bird) appear to match the super constructor (for Food). Unless you plan to add extra functionality in the sub-class constructors, I would remove those overrides. This is for multiple reasons, including but not limited to:

  • If the signature of the super constructor changes, then the sub-class constructors also need to be updated



  • If there happened to be a typo or other mistake in those sub-class constructors, that would be an avoidable error.



Memoization

While it likely won't make much difference, the function getKeyAtIndex could be optimized by using memoization - this could be achieved by storing the keys in another variable and then having that function merely reference the array of keys instead of calling Object.keys() in each call. While this may not make much of a difference in this example, it could make a larger difference in a larger project. Take a look at this answer for more information.

Context

StackExchange Code Review Q#154551, answer score: 2

Revisions (0)

No revisions yet.