1

Want to extract every marketID from every market that has a marketName == 'Moneyline'. Tried a few combinations of .maps, .rejects, and/or .selects but can't narrow it down as the complicated structure is confusing me.

There are many markets in events, and there are many events as well. A sample of the structure (tried to edit it for brevity):

{"currencyCode"=>"GBP",
"eventTypes"=>[
    {"eventTypeId"=>6423,
    "eventNodes"=>[
        {"eventId"=>28017227,
        "event"=>
            {"eventName"=>"Philadelphia @ Seattle"
            },
            "marketNodes"=>[
                {"marketId"=>"1.128274650",
                "description"=>
                    {"marketName"=>"Moneyline"}
                },
                {"marketId"=>"1.128274625",
                "description"=>
                    {"marketName"=>"Winning Margin"}
                }}}]},
        {"eventId"=>28018251,
        "event"=>
            {"eventName"=>"Arkansas @ Mississippi State"
            },
            "marketNodes"=>[
                {"marketId"=>"1.128299882",
                "description"=>
                    {"marketName"=>"Under/Over 60.5pts"}
                },
                {"marketId"=>"1.128299881",
                "description"=>
                    {"marketName"=>"Moneyline"}
                }}}]},
        {"eventId"=> etc....

Tried all kinds of things, for example,

markets = json["eventTypes"].first["eventNodes"].map {|e| e["marketNodes"].map { |e| e["marketId"] } if (e["marketNodes"].map {|e| e["marketName"] == 'Moneyline'})}
markets.flatten
# => yields every marketId not every marketId with marketName of 'Moneyline'

Getting a simple array with every marketId from Moneyline markets with no other information is sufficient. Using Rails methods is fine too if preferred.

Sorry if my editing messed up the syntax. Here's the source. It looks like this only with => instead of : after parsing the JSON.

Thank you!

3
  • rather not use outside resources. this is in a rails app so either ruby or rails methods Commented Nov 19, 2016 at 22:28
  • Do you have an example with correct syntax? Commented Nov 19, 2016 at 22:37
  • 1
    @EricDuminil Sorry if my editing messed it up. See here: betfair.com/www/sports/exchange/readonly/v1/… In my console, it basically looks exactly like that only with => instead of : after parsing. It's a little messy. Commented Nov 19, 2016 at 22:38

2 Answers 2

2

I love nested maps and selects :D

require 'json'

hash = JSON.parse(File.read('data.json'))

moneyline_market_ids = hash["eventTypes"].map{|type|
  type["eventNodes"].map{|node|
    node["marketNodes"].select{|market|
      market["description"]["marketName"] == 'Moneyline'
    }.map{|market| market["marketId"]}
  }
}.flatten

puts moneyline_market_ids.join(', ')
#=> 1.128255531, 1.128272164, 1.128255516, 1.128272159, 1.128278718, 1.128272176, 1.128272174, 1.128272169, 1.128272148, 1.128272146, 1.128255464, 1.128255448, 1.128272157, 1.128272155, 1.128255499, 1.128272153, 1.128255484, 1.128272150, 1.128255748, 1.128272185, 1.128278720, 1.128272183, 1.128272178, 1.128255729, 1.128360712, 1.128255371, 1.128255433, 1.128255418, 1.128255403, 1.128255387
Sign up to request clarification or add additional context in comments.

4 Comments

yowza. perfect. Thank you kindly! My head was hurting trying to figure it out.
Hey @eric-duminil, if you have a minute to spare, I have a more challenging brain teaser here. Source: betfair.com/www/sports/exchange/readonly/v1/…. I want to select marketIds == 'Moneyline' but only those with countryCode == 'US' || 'GB' OR eventName.include?(' @ '). (space before and after the @). I tried different combos of map and select but some nodes don't have 'countryCode` which complicates things. There is some overlap with those last two criteria, so uniq may be necessry? TIA!
Please write another question.
Right! stackoverflow.com/questions/40708340/…. Really do appreciate it!
1

Just for fun, here's another possible answer, this time with regexen. It is shorter but might break depending on your input data. It reads the json data directly as String :

json = File.read('data.json')

market_ids   = json.scan(/(?<="marketId":")[\d\.]+/)
market_names = json.scan(/(?<="marketName":")[^"]+/)

moneyline_market_ids = market_ids.zip(market_names).select{|id,name| name=="Moneyline"}.map{|id,_| id}
puts moneyline_market_ids.join(', ')
#=> 1.128255531, 1.128272164, 1.128255516, 1.128272159, 1.128278718, 1.128272176, 1.128272174, 1.128272169, 1.128272148, 1.128272146, 1.128255464, 1.128255448, 1.128272157, 1.128272155, 1.128255499, 1.128272153, 1.128255484, 1.128272150, 1.128255748, 1.128272185, 1.128278720, 1.128272183, 1.128272178, 1.128255729, 1.128360712, 1.128255371, 1.128255433, 1.128255418, 1.128255403, 1.128255387

It outputs the same result as the other answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.