I'm trying to write a function in Ruby which can take in a in an array of arrays, and convert it into a hash. This will be used to simulate grammar and generate random sentences. The resulting map will be helpful in generating all combination of sentences available with the current grammar rules.
The array of arrays to be input is in the following format:
[
["<start>", "The <object> <verb> tonight."],
["<object>", "waves", "big yellow flowers", "slugs"],
["<verb>", "sigh <adverb>", "portend like <object>", "die <adverb>"],
["<adverb>", "warily", "grumpily"]
]
After passing this into the function, and mapping it, the result should be as such:
{
"<start>"=>[ ["The", "<object>", "<verb>", "tonight."] ],
"<object>"=>[ ["waves"] , ["big", "yellow", "flowers"] , ["slugs"] ],
"<verb>"=>[ ["sigh", "<adverb>"] , ["portend", "like", "<object>"] , ["die", "<adverb>"] ],
"<adverb>"=>[ ["warily"] , ["grumpily"] ]
}
For each non-terminals, it should map its corresponding productions to it. For example, will contain "warily" and "grumpily" as those two are the productions corresponding to the non-terminal .
How do I go about achieving this? I'm a bit lost as to where to start.
Try this:
arr = [ ["<start>", "The <object> <verb> tonight."],
["<object>", "waves", "big yellow flowers", "slugs"],
["<verb>", "sigh <adverb>", "portend like <object>", "die <adverb>"],
["<adverb>", "warily", "grumpily"] ]
arr.map { |ar| [ar.shift, ar.map { |str| str.split }] }.to_h
#=>
#{ "<start>" => [["The", "<object>", "<verb>", "tonight."]],
# "<object>" => [["waves"], ["big", "yellow", "flowers"], ["slugs"]],
# "<verb>" => [["sigh", "<adverb>"], ["portend", "like", "<object>"], ["die", "<adverb>"]],
# "<adverb>" => [["warily"], ["grumpily"]] }
ar.shift
takes the first element of each subarray. The block used with ar.map
splits (on whitespace) the remaining elements into arrays. Finally to_h
converts the resulting array into a hash.