Find data in Hashes using dot notation queries.
We use QueryableHash to parse Ruby Hashes built from JSON API data. It works especially well when the target data is erratic.
data = {
glossary: {
title: "example glossary",
gloss_div: {
title: "S",
gloss_list: {
gloss_entry: {
id: "SGML",
sort_as: "SGML",
gloss_term: "Standard Generalized Markup Language",
acronym: "SGML",
abbrev: "ISO 8879:1986",
gloss_def: {
para: "A meta-markup language, used to create markup languages such as DocBook.",
gloss_see_also: ["GML", "XML"]
},
gloss_see: "markup"
}
}
}
}
}
queryable = QueryableHash.wrap(data)
queryable.get("glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
queryable = QueryableHash.wrap(data)
queryable.get("this.key.does.not.exist", "glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
queryable = QueryableHash.wrap(data)
queryable.get_all(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
)
#=> [ "example glossary",
# "Standard Generalized Markup Language",
# "A meta-markup language, used to create markup languages such as DocBook." ]
# or assign the results
title, term, para = queryable.get_all(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
)
title #=> "example glossary",
term #=> "Standard Generalized Markup Language"
param #=> "A meta-markup language, used to create markup languages such as DocBook."
queryable = QueryableHash.wrap(data)
queryable.get("this.key.does.not.exist") #=> nil
queryable = QueryableHash.wrap(data)
queryable.get("this.key.does.not.exist", nil_value: "missing") #=> "missing"
queryable = QueryableHash.wrap(data)
queryable.get("this.key.does.not.exist", raise_when_nil: true) #=> raises QueryableHash::NotFoundError
queryable = QueryableHash.wrap(data, nil_value: "missing")
queryable.get("this.key.does.not.exist") #=> "missing"
queryable.get("neither.does.this.one") #=> "missing"
queryable.get("nor.this.one", nil_value: nil) #=> nil
queryable = QueryableHash.wrap(data, raise_when_nil: true)
queryable.get("this.key.does.not.exist") #=> raises QueryableHash::NotFoundError
queryable.get("neither.does.this.one") #=> raises QueryableHash::NotFoundError
queryable.get("nor.this.one", raise_when_nil: false) #=> nil
Also check out: https://github.com/joshbuddy/jsonpath