The goal of the project is to make a MadLib. I want the array to shuffle each time the mouse is clicked, how would I go about doing that?
String madLib = "I went to #place# with #person#. I know #person# from when we #event#. At #place# we saw #thing#. It was #adjective# so we ran away to #otherPlace#. ";
String[] array1 = {"Pakistan", "The Pentagon", "Universal Studios Sound Stage No. 5", "The basement of the United States Embassy in Iran", "Uncle Randy's Attic"};
String[] array2 = {"Former President Bill Clinton", "Ten Dolla Founding Fatha Alexander Hamilton", "Former Bufffalo Bills Running Back Orenthal James 'OJ' Simpson ", "Clifford From Clifford The Big Red Dog", "Director and 2 time oscar winner Quentin Tarantino "};
String[] array3 = {"Stole the entire contents of Fort Knox", "Taught John D. Rockefeller how to get oil", "Tried to but failed to prevent the Cold War", "Tried to save Brandon Lee", "Attemted to rob a Boost Mobile and got locked in"};
String[] array4 = {"A taxidermied lion with three legs ", "cryogenically frozen Walt Disney", "A below average height but above average speed brown colored horse", "A bucket of warm cow milk", "A replica of political podcaster Ben Shapiro"};
String[] array5 = {"Barking", "Running around", "Eating the Travis Scott meal from McDonalds", "Watching Season 1 of Mickeymouse Clubhouse", "Verbally abusing a cardboard cutout of Air Buddy for the Air Bud movies"};
String[] array6 = {"A random house", "the museum of cats", "The dog adoption center", "The Wendys drivethrough line", "The window and light fixture store"};
void setup() {
}
void draw(){
}
void mousePressed(){
int index1 = int(random(array1.length));
int index2 = int(random(array2.length));
int index3 = int(random(array3.length));
int index4 = int(random(array4.length));
int index5 = int(random(array5.length));
int index6 = int(random(array6.length));
madLib = madLib.replace("#place#", (array1[index1]));
madLib = madLib.replace("#person#", (array2[index2]));
madLib = madLib.replace("#event#", (array3[index3]));
madLib = madLib.replace("#thing#", (array4[index4]));
madLib = madLib.replace("#adjective#", (array5[index5]));
madLib = madLib.replace("#otherPlace#", (array6[index6]));
println(madLib);
}
What you have written in mousePressed modifies the original madLib string, replacing all the hash delimited parameters with new information. That works fine the first time it is run and the string that is printed has those parameters replaced so you get the right output.
But now the madLib string doesn't contain any hash delimited parameters, so when mousePressed runs again none of the replace commands does anything because the hash delimited parameters they are replacing no longer exist.
So you need to modify a copy of the string and do your replacements on the copy and leave the original string alone. Thanks to #GeorgeProfenza for this code sample:
String madLib = "I went to #place# with #person#. I know #person# from when we #event#. At #place# we saw #thing#. It was #adjective# so we ran away to #otherPlace#. ";
String[] array1 = {"Pakistan", "The Pentagon", "Universal Studios Sound Stage No. 5", "The basement of the United States Embassy in Iran", "Uncle Randy's Attic"};
String[] array2 = {"Former President Bill Clinton", "Ten Dolla Founding Fatha Alexander Hamilton", "Former Bufffalo Bills Running Back Orenthal James 'OJ' Simpson ", "Clifford From Clifford The Big Red Dog", "Director and 2 time oscar winner Quentin Tarantino "};
String[] array3 = {"Stole the entire contents of Fort Knox", "Taught John D. Rockefeller how to get oil", "Tried to but failed to prevent the Cold War", "Tried to save Brandon Lee", "Attemted to rob a Boost Mobile and got locked in"};
String[] array4 = {"A taxidermied lion with three legs ", "cryogenically frozen Walt Disney", "A below average height but above average speed brown colored horse", "A bucket of warm cow milk", "A replica of political podcaster Ben Shapiro"};
String[] array5 = {"Barking", "Running around", "Eating the Travis Scott meal from McDonalds", "Watching Season 1 of Mickeymouse Clubhouse", "Verbally abusing a cardboard cutout of Air Buddy for the Air Bud movies"};
String[] array6 = {"A random house", "the museum of cats", "The dog adoption center", "The Wendys drivethrough line", "The window and light fixture store"};
void setup() {
}
void draw() {
}
void mousePressed() {
int index1 = int(random(array1.length));
int index2 = int(random(array2.length));
int index3 = int(random(array3.length));
int index4 = int(random(array4.length));
int index5 = int(random(array5.length));
int index6 = int(random(array6.length));
String madLibResult = madLib.replace("#place#", (array1[index1]));
madLibResult = madLibResult.replace("#person#", (array2[index2]));
madLibResult = madLibResult.replace("#event#", (array3[index3]));
madLibResult = madLibResult.replace("#thing#", (array4[index4]));
madLibResult = madLibResult.replace("#adjective#", (array5[index5]));
madLibResult = madLibResult.replace("#otherPlace#", (array6[index6]));
println(madLibResult);
}
I have some JSON returned from Google Maps API.
{"results"=>
[{"address_components"=>
[{"long_name"=>"1600", "short_name"=>"1600", "types"=>["street_number"]},
{"long_name"=>"President's Park",
"short_name"=>"President's Park",
"types"=>["establishment"]},
{"long_name"=>"Pennsylvania Avenue Northwest",
"short_name"=>"Pennsylvania Ave NW",
"types"=>["route"]},
{"long_name"=>"Washington",
"short_name"=>"Washington",
"types"=>["locality", "political"]},
{"long_name"=>"District of Columbia",
"short_name"=>"DC",
"types"=>["administrative_area_level_1", "political"]},
{"long_name"=>"United States",
"short_name"=>"US",
"types"=>["country", "political"]},
{"long_name"=>"20500", "short_name"=>"20500", "types"=>["postal_code"]}],
"formatted_address"=>
"1600 Pennsylvania Avenue Northwest, President's Park, Washington, DC 20500, USA",
"geometry"=>
{"location"=>{"lat"=>38.8977332, "lng"=>-77.0365305},
"location_type"=>"ROOFTOP",
"viewport"=>
{"northeast"=>{"lat"=>38.8990821802915, "lng"=>-77.0351815197085},
"southwest"=>{"lat"=>38.8963842197085, "lng"=>-77.03787948029151}}},
"partial_match"=>true,
"types"=>["street_address"]}],
"status"=>"OK"}
I'm trying to access the latitude and longitude like so:
parsed = JSON.parse(data)
p parsed["results"]["location"]["lat"]
p parsed["results"]["location"]["lng"]
When I do so, my code throws and error: "no implicit conversion of String into Integer (TypeError).
I will be very grateful to anyone who can shed some light onto my problem. Thank you.
So, in your case it would be
p parsed["results"][0]["geometry"]["location"]
# => {"lat"=>38.8977332, "lng"=>-77.0365305}
I'm a Java guy, new to Ruby. I've been playing with it just to see what it can do, and I'm running into an issue that I can't solve.
I decided to try out Sinatra, again, just to see what it can do, and decided to play with the ESPN API and see if I can pull the venue of a team via the API.
I'm able to make the call and get the data back, but I am having trouble parsing it:
{"sports"=>[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}], "resultsOffset"=>0, "resultsLimit"=>50, "resultsCount"=>1, "timestamp"=>"2013-08-04T14:47:13Z", "status"=>"success"}
I want to pull the venues part of the object, specifically the name value. Every time I try to parse it I end up getting an error along the lines of "cannot change from nil to string" and then also I've gotten an integer to string error.
Here's what i have so far:
get '/venue/:team' do
id = ids[params[:team]]
url = 'http://api.espn.com/v1/sports/baseball/mlb/teams/' + id + '?enable=venues&apikey=' + $key
resp = Net::HTTP.get_response(URI.parse(url))
data = resp.body
parsed = JSON.parse(resp.body)
#venueData = parsed["sports"]
"Looking for the venue of the #{params[:team]}, which has id " + id + ", and here's the data returned: " + venueData.to_s
end
When I do parsed["sports"} I get:
[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}]
But nothing else parses. Please help!
Like I said, I'm not trying to do anything fancy, just figure out Ruby a little for fun, but I have been stuck on this issue for days now. Any help would be appreciated!
EDIT:
JSON straight from the API:
{"sports" :[{"name" :"baseball","id" :1,"uid" :"s:1","leagues" :[{"name" :"Major League Baseball","abbreviation" :"mlb","id" :10,"uid" :"s:1~l:10","groupId" :9,"shortName" :"MLB","teams" :[{"id" :17,"uid" :"s:1~l:10~t:17","location" :"Cincinnati","name" :"Reds","abbreviation" :"CIN","color" :"D60042","venues" :[{"id" :83,"name" :"Great American Ball Park","city" :"Cincinnati","state" :"Ohio","country" :"","capacity" :0}],"links" :{"api" :{"teams" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17"},"news" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"},"notes" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}},"web" :{"teams" :{"href" :"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}},"mobile" :{"teams" :{"href" :"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}],"resultsOffset" :0,"resultsLimit" :50,"resultsCount" :1,"timestamp" :"2013-08-05T19:44:32Z","status" :"success"}
The result of data.inspect:
"{\"sports\" :[{\"name\" :\"baseball\",\"id\" :1,\"uid\" :\"s:1\",\"leagues\" :[{\"name\" :\"Major League Baseball\",\"abbreviation\" :\"mlb\",\"id\" :10,\"uid\" :\"s:1~l:10\",\"groupId\" :9,\"shortName\" :\"MLB\",\"teams\" :[{\"id\" :17,\"uid\" :\"s:1~l:10~t:17\",\"location\" :\"Cincinnati\",\"name\" :\"Reds\",\"abbreviation\" :\"CIN\",\"color\" :\"D60042\",\"venues\" :[{\"id\" :83,\"name\" :\"Great American Ball Park\",\"city\" :\"Cincinnati\",\"state\" :\"Ohio\",\"country\" :\"\",\"capacity\" :0}],\"links\" :{\"api\" :{\"teams\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17\"},\"news\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news\"},\"notes\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes\"}},\"web\" :{\"teams\" :{\"href\" :\"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public\"}},\"mobile\" :{\"teams\" :{\"href\" :\"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public\"}}}}]}]}],\"resultsOffset\" :0,\"resultsLimit\" :50,\"resultsCount\" :1,\"timestamp\" :\"2013-08-05T19:44:24Z\",\"status\" :\"success\"}"
parsed["sports"] does not exist, parse your input and inspect it/ dump it
With the data you've provided in the question, you can get to the venues information like this:
require 'json'
json = JSON.parse data
json["sports"].first["leagues"].first["teams"].first["venues"]
# => [{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}]
By replacing each of the first calls with an iterator, you can search through without knowing where the data is:
json["sports"].each{|h|
h["leagues"].each{|h|
h["teams"].each{|h|
venues = h["venues"].map{|h| h["name"]}.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
}
}
This outputs:
name: Cincinnati Reds venues: Great American Ball Park
Depending on how stable the response data is you may be able to cut out several of the iterators:
json["sports"].first["leagues"]
.first["teams"]
.each{|h|
venues = h["venues"].map{|h| h["name"] }.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
and you'll most likely want to save the data, so something like each_with_object is helpful:
team_and_venues = json["sports"].first["leagues"]
.first["teams"]
.each_with_object([]){|h,xs|
venues = h["venues"].map{|h| h["name"]}.join(", ")
xs << %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
team_and_venues
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
Notice that when an iterator declares variables, even if there is a variable with the same name outside the block, the scope of the block is respected and the block's variables remain local.
That's some pretty ugly code if you ask me, but it's a place to start.
I think I am getting myself massively confused here in Ruby...
I have an array:
array1 = [["4b411f2bf964a52082c125e3", "The Three Pigeons", 51.236318, -0.57055], ["4b444648f964a52049f325e3", "The Royal Oak", 51.23555937678702, -0.5702378403809515], ["4b92c695f964a520aa1a34e3", "Slug And Lettuce", 51.237156, -0.571021], ["4b490136f964a520a56126e3", "The Robin Hood", 51.23603403568268, -0.568686], ["4b425f85f964a52092d225e3", "The Guildford Tup", 51.237734, -0.5703823], ["4b48f87ff964a520096026e3", "The Keep", 51.234704, -0.572574], ["4b426369f964a520e3d225e3", "The Five & Lime", 51.236908, -0.573695], ["4b56243af964a5204f0228e3", "The Albany", 51.23687122552597, -0.5666781994529876], ["4b426047f964a520a4d225e3", "The Kings Head", 51.234176, -0.573656], ["4b4261e4f964a520c6d225e3", "The Live and Let Live", 51.238477, -0.573306], ["4b425ec9f964a52086d225e3", "The Star Inn - Shepherd Neame", 51.23501026190194, -0.5749610066413879], ["4cb995490180721e03e09461", "Prince Albert", 51.242471, -0.572899], ["4e02726dc65b8061424b59f1", "Bar Mambo", 51.236896, -0.577263], ["4b7451e5f964a520fad42de3", "The Rodboro Buildings (Wetherspoon)", 51.236624141592365, -0.5775332450866699], ["4b6de739f964a520769a2ce3", "The White House", 51.23463575311113, -0.5773776769638062], ["4bb504a30ef1c9b6dbc2f412", "The Britannia - Shepherd Neame", 51.233105063438416, -0.5760687589645386], ["4b4447f8f964a5206cf325e3", "The George Abbot", 51.235186599066246, -0.5779409408569336], ["4b894378f964a520e72632e3", "The Boatman", 51.23155028087051, -0.572927], ["4bb475f449bdc9b65bcb0c10", "The Keystone", 51.23437208365849, -0.5779758095741272], ["4ba55291f964a5209afa38e3", "Rogues Bar", 51.23763173808256, -0.5610001087188721], ["4b40ce65f964a5205ebb25e3", "The Drummond", 51.24133950313797, -0.5758380889892578], ["4b48c8a8f964a520cb5626e3", "The Stok", 51.24272843225208, -0.5718989403261525], ["4c4f275651c2c9288af1859f", "The Parkway", 51.248229, -0.569356], ["4b48a60ff964a5208c5126e3", "The King's Head", 51.24666037427897, -0.5728936419289142], ["4b9a86c4f964a520f2bd35e3", "Ye Olde Ship Inn", 51.225673503520696, -0.5796146392822266], ["4c582015a7d976b0130cddee", "Wates House", 51.2420380341127, -0.5908584594726562], ["4b484917f964a520184b26e3", "The Rowbarge", 51.25055105804697, -0.5729025186239382], ["4bd86cb6e914a593c92f53fa", "The Wooden Bridge", 51.248547, -0.58514], ["4bd8b0442e6f0f4754240808", "The Seahorse", 51.218605041503906, -0.569018], ["4bb61c6bef159c74ff6b75f7", "The Astolat Public House", 51.23704061748392, -0.5893993377685547], ["4c978b274f16b71312c2ce3f", "The Queen Victoria", 51.21475338935852, -0.567119], ["4bb0eb08f964a520006a3ce3", "Anchor & Horseshoes", 51.254823, -0.548787], ["4c126e3c82a3c9b60ab0f9f8", "The Garage Tavern", 51.261162, -0.586647], ["4bed4208bac3c9b692fcfde9", "The Cricketers", 51.254246288978116, -0.6047425123927289], ["4b92cb0bf964a520501c34e3", "Horse & Groom", 51.24614672635736, -0.5279016494750977], ["4e8b7820be7b1b0656b1f927", "Apple Tree Pub", 51.2460676, -0.61427766], ["4dc58ce152b1e8f9f7d7378b", "Royal Oak", 51.248792, -0.626987], ["4c1a1c70838020a137aae661", "Withies Inn", 51.21199, -0.621551], ["4baded59f964a52031733be3", "The Jolly Farmer", 51.194106, -0.558244], ["4e21b6f052b1f82ffba120b5", "Compton Royal British Legion", 51.21349872454546, -0.6290990092597657], ["4b646071f964a52052ae2ae3", "The Jolly Farmer", 51.27866916930163, -0.5856227874755859], ["4d987f7961a3a1cd32aace42", "White Hart", 51.25011, -0.636736], ["4c8ccb34509e3704d9533655", "The Harrow Inn", 51.213387, -0.6316709518432617], ["4b71bb30f964a5200b592de3", "Bull's Head", 51.253260091783105, -0.5042177438735962], ["4f63b0b5e4b087553c2ae4fa", "The freeholders", 51.194189, -0.603889], ["4bc762a32f94d13aebd2117f", "The Cricketers", 51.194975, -0.608211], ["4be6c014bcef2d7f476805e5", "Worplesdon Place (Beef Eater Grill)", 51.27501810816803, -0.6078529357910156], ["4dbd63785da3ff58ec6192b1", "Scratchers", 51.19211, -0.60234], ["4e687a6bb3ad5d9197518ed6", "Three Lions - Shepherd Neame", 51.19198564344851, -0.6023865938186646], ["4c714ddcb5a5236acb995252", "The White heart Pub", 51.200254, -0.603593]]
I pass these results to an API that scores them. The result I get back is an array with lots of hashes in them. The Key is the ID from the array1 and the value is the score
array2 = [{"4bed4208bac3c9b692fcfde9"=>743.0}, {"4e21b6f052b1f82ffba120b5"=>789.0}, {"4b646071f964a52052ae2ae3"=>921.0}, {"4bb504a30ef1c9b6dbc2f412"=>99.0}, {"4b426369f964a520e3d225e3"=>80.0}, {"4c4f275651c2c9288af1859f"=>254.0}, {"4b92cb0bf964a520501c34e3"=>468.0}, {"4b425f85f964a52092d225e3"=>27.0}, {"4bd86cb6e914a593c92f53fa"=>512.0}, {"4e687a6bb3ad5d9197518ed6"=>622.0}, {"4b4447f8f964a5206cf325e3"=>73.0}, {"4b425ec9f964a52086d225e3"=>26.0}, {"4b484917f964a520184b26e3"=>328.0}, {"4b426047f964a520a4d225e3"=>37.0}, {"4c978b274f16b71312c2ce3f"=>253.0}, {"4b6de739f964a520769a2ce3"=>81.0}, {"4b48c8a8f964a520cb5626e3"=>167.0}, {"4bb475f449bdc9b65bcb0c10"=>80.0}, {"4c126e3c82a3c9b60ab0f9f8"=>739.0}, {"4bd8b0442e6f0f4754240808"=>210.0}, {"4bb61c6bef159c74ff6b75f7"=>231.0}, {"4b56243af964a5204f0228e3"=>56.0}, {"4b411f2bf964a52082c125e3"=>0.0}, {"4b48a60ff964a5208c5126e3"=>211.0}, {"4baded59f964a52031733be3"=>514.0}, {"4b40ce65f964a5205ebb25e3"=>124.0}, {"4b444648f964a52049f325e3"=>81.0}, {"4bb0eb08f964a520006a3ce3"=>376.0}, {"4f63b0b5e4b087553c2ae4fa"=>586.0}, {"4b9a86c4f964a520f2bd35e3"=>192.0}, {"4cb995490180721e03e09461"=>125.0}, {"4dc58ce152b1e8f9f7d7378b"=>955.0}, {"4b92c695f964a520aa1a34e3"=>20.0}, {"4c582015a7d976b0130cddee"=>484.0}, {"4c8ccb34509e3704d9533655"=>743.0}, {"4b48f87ff964a520096026e3"=>48.0}, {"4c1a1c70838020a137aae661"=>640.0}, {"4b894378f964a520e72632e3"=>55.0}, {"4e8b7820be7b1b0656b1f927"=>666.0}, {"4e02726dc65b8061424b59f1"=>78.0}, {"4b4261e4f964a520c6d225e3"=>57.0}, {"4ba55291f964a5209afa38e3"=>77.0}, {"4c714ddcb5a5236acb995252"=>473.0}, {"4b7451e5f964a520fad42de3"=>80.0}, {"4b490136f964a520a56126e3"=>71.0}, {"4d987f7961a3a1cd32aace42"=>1008.0}, {"4dbd63785da3ff58ec6192b1"=>622.0}, {"4b71bb30f964a5200b592de3"=>640.0}, {"4be6c014bcef2d7f476805e5"=>1016.0}, {"4bc762a32f94d13aebd2117f"=>577.0}]
I would like to end up with a new array that includes the value of the matched key in array 2 to array 1 e.g.
["4c714ddcb5a5236acb995252", "The White heart Pub", 51.200254, -0.603593, 622]
Not every value in array1 will get a score, some will not get anything and as a result they will not be returned in array2 at all. So I need to match them by id("4c714ddcb5a5236acb995252") and check if they are present and then match. the score with the data in array1
Array.assoc is nice for this:
array2.each{|h| array1.assoc(h.keys.first) << h.values.first}
p array1
Since these should be hashes, lets turn them into ones:
h1 = array1.each_with_object({}) { |a, h| h[a.first] = a[1..-1] }
#=> {"4b411f2bf964a52082c125e3"=>["The Three Pigeons", 51.236318, -0.57055], ... }
h2 = array2.inject(:merge)
#=> {"4bed4208bac3c9b692fcfde9"=>743.0, ... }
then we can easily create a final hash:
result = h2.each { |k, v| h1[k] << v }
#=> {"4b411f2bf964a52082c125e3"=>["The Three Pigeons", 51.236318, -0.57055, 0.0], ... }
note that this will break if h2 has a key that h1 doesn't already (or, more specifically, that h1's key's value isn't an array).
If you really want this in the array form you give, you can do:
result = result.map { |k, v| v.unshift(k) }
#=> [["4b411f2bf964a52082c125e3", "The Three Pigeons", 51.236318, -0.57055, 0.0], ... ]
I would use map from Enumerable like this:
array3 = array2.map do |item_from_array2|
id = item_from_array2.keys[0]
item_from_array1 = array1.find { |item| item.include?(id) }
item_from_array1.dup << item_from_array2[id]
end
Here, I enumerate over the items in array2 so that the result only contains items that exist in array2. Then, I get the id and search for the array in array1 that has that id. Then, add the value from array2 to the end of the item found from array1. Finally, map makes an array from every returned value.
As a performance consideration, you may want to create a hash from the first array that you can index by the id because calling array1.find every iteration will be slower than using hash1[id] every iteration.