FlameDra FlameDra - 1 month ago 11
Ruby Question

Creating a map from an array of arrays in Ruby

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.

Answer

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"]] }