Reputation: 595
Hi I am working on a Ruby on Rails project with ruby-2.5.0 and rails 5. I have a hash which can be of different format. I have certain words to search in this hash if any of the word exist in the hash return true with the word. word can be a key or value.
Json Format Example:
{
"data": {
"Lines": [{
"Words": [{
"WordText": "Walmart",
"Left": 63,
"Top": 33,
"Height": 72,
"Width": 364
}],
"MaxHeight": 72,
"MinTop": 33
},
{
"Words": [{
"WordText": "Save",
"Left": 70,
"Top": 116,
"Height": 26,
"Width": 68
},
{
"WordText": "money.",
"Left": 148,
"Top": 123,
"Height": 25,
"Width": 108
},
{
"WordText": "Live",
"Left": 267,
"Top": 118,
"Height": 25,
"Width": 59
},
{
"WordText": "better.",
"Left": 335,
"Top": 117,
"Height": 26,
"Width": 100
}
],
"MaxHeight": 26,
"MinTop": 116
},
{
"Words": [{
"WordText": "srg",
"Left": 53,
"Top": 176,
"Height": 20,
"Width": 36
},
{
"WordText": "2006",
"Left": 105,
"Top": 176,
"Height": 21,
"Width": 49
},
{
"WordText": "00006167",
"Left": 222,
"Top": 177,
"Height": 21,
"Width": 100
},
{
"WordText": "03",
"Left": 390,
"Top": 178,
"Height": 22,
"Width": 23
},
{
"WordText": "04247",
"Left": 480,
"Top": 179,
"Height": 21,
"Width": 62
}
],
"MaxHeight": 22,
"MinTop": 176
},
{
"Words": [{
"WordText": "MOTOR",
"Left": 53,
"Top": 201,
"Height": 22,
"Width": 63
},
{
"WordText": "OIL",
"Left": 132,
"Top": 201,
"Height": 22,
"Width": 36
}
],
"MaxHeight": 22,
"MinTop": 201
},
{
"Words": [{
"WordText": "007310200289",
"Left": 230,
"Top": 202,
"Height": 22,
"Width": 152
}],
"MaxHeight": 22,
"MinTop": 202
},
{
"Words": [{
"WordText": "SUBTOTAL",
"Left": 297,
"Top": 227,
"Height": 22,
"Width": 101
}],
"MaxHeight": 22,
"MinTop": 227
},
{
"Words": [{
"WordText": "21.97",
"Left": 474,
"Top": 228,
"Height": 21,
"Width": 61
}],
"MaxHeight": 21,
"MinTop": 228
},
{
"Words": [{
"WordText": "TAX",
"Left": 175,
"Top": 250,
"Height": 22,
"Width": 36
},
{
"WordText": "1",
"Left": 228,
"Top": 251,
"Height": 21,
"Width": 7
}
],
"MaxHeight": 22,
"MinTop": 250
},
{
"Words": [{
"WordText": "7.700",
"Left": 283,
"Top": 251,
"Height": 21,
"Width": 62
}],
"MaxHeight": 21,
"MinTop": 251
},
{
"Words": [{
"WordText": "1.69",
"Left": 488,
"Top": 252,
"Height": 21,
"Width": 47
}],
"MaxHeight": 21,
"MinTop": 252
},
{
"Words": [{
"WordText": "rorAL",
"Left": 337,
"Top": 275,
"Height": 22,
"Width": 61
}],
"MaxHeight": 22,
"MinTop": 275
},
{
"Words": [{
"WordText": "23.66",
"Left": 474,
"Top": 276,
"Height": 22,
"Width": 61
}],
"MaxHeight": 22,
"MinTop": 276
},
{
"Words": [{
"WordText": "SHOPPING",
"Left": 160,
"Top": 299,
"Height": 21,
"Width": 101
},
{
"WordText": "CARD",
"Left": 277,
"Top": 299,
"Height": 22,
"Width": 48
},
{
"WordText": "TEND",
"Left": 341,
"Top": 300,
"Height": 21,
"Width": 49
}
],
"MaxHeight": 22,
"MinTop": 299
},
{
"Words": [{
"WordText": "23.66",
"Left": 474,
"Top": 300,
"Height": 22,
"Width": 61
}],
"MaxHeight": 22,
"MinTop": 300
},
{
"Words": [{
"WordText": "CHANGE",
"Left": 269,
"Top": 324,
"Height": 21,
"Width": 74
},
{
"WordText": "DUE",
"Left": 359,
"Top": 324,
"Height": 21,
"Width": 36
}
],
"MaxHeight": 21,
"MinTop": 324
},
{
"Words": [{
"WordText": "07/21/15",
"Left": 61,
"Top": 386,
"Height": 22,
"Width": 101
}],
"MaxHeight": 22,
"MinTop": 386
},
{
"Words": [{
"WordText": "ITEMS",
"Left": 173,
"Top": 455,
"Height": 42,
"Width": 120
},
{
"WordText": "SOLD",
"Left": 326,
"Top": 456,
"Height": 41,
"Width": 96
},
{
"WordText": "I",
"Left": 458,
"Top": 457,
"Height": 40,
"Width": 11
}
],
"MaxHeight": 42,
"MinTop": 455
},
{
"Words": [{
"WordText": "Washington",
"Left": 88,
"Top": 539,
"Height": 23,
"Width": 129
},
{
"WordText": "E-Cycles:",
"Left": 226,
"Top": 539,
"Height": 23,
"Width": 106
},
{
"WordText": "Free",
"Left": 341,
"Top": 540,
"Height": 18,
"Width": 50
},
{
"WordText": "Recycling",
"Left": 400,
"Top": 540,
"Height": 24,
"Width": 107
}
],
"MaxHeight": 24,
"MinTop": 539
},
{
"Words": [{
"WordText": "For",
"Left": 103,
"Top": 568,
"Height": 18,
"Width": 37
},
{
"WordText": "Computers,",
"Left": 148,
"Top": 568,
"Height": 23,
"Width": 126
},
{
"WordText": "Monitors,",
"Left": 283,
"Top": 569,
"Height": 21,
"Width": 100
},
{
"WordText": "and",
"Left": 392,
"Top": 570,
"Height": 18,
"Width": 40
},
{
"WordText": "TV's",
"Left": 441,
"Top": 570,
"Height": 18,
"Width": 48
}
],
"MaxHeight": 23,
"MinTop": 568
},
{
"Words": [{
"WordText": "www.ecyclewashington.org",
"Left": 52,
"Top": 597,
"Height": 24,
"Width": 301
},
{
"WordText": "1-800-RECYCLE",
"Left": 363,
"Top": 598,
"Height": 19,
"Width": 185
}
],
"MaxHeight": 24,
"MinTop": 597
},
{
"Words": [{
"WordText": "Lou",
"Left": 49,
"Top": 643,
"Height": 20,
"Width": 36
},
{
"WordText": "Prices",
"Left": 101,
"Top": 643,
"Height": 21,
"Width": 75
},
{
"WordText": "You",
"Left": 192,
"Top": 643,
"Height": 21,
"Width": 36
},
{
"WordText": "Can",
"Left": 244,
"Top": 644,
"Height": 21,
"Width": 35
},
{
"WordText": "Trust.",
"Left": 295,
"Top": 644,
"Height": 21,
"Width": 72
},
{
"WordText": "Every",
"Left": 386,
"Top": 644,
"Height": 23,
"Width": 62
},
{
"WordText": "Day.",
"Left": 463,
"Top": 645,
"Height": 21,
"Width": 47
}
],
"MaxHeight": 23,
"MinTop": 643
},
{
"Words": [{
"WordText": "07/21/15",
"Left": 145,
"Top": 668,
"Height": 22,
"Width": 100
}],
"MaxHeight": 22,
"MinTop": 668
}
],
"HasOverlay": true,
"Message": "Total lines: 22",
"ParsedText": "Walmart"
}
}
Suppose i have an array of words ["Walmart","Optical","Anker"]. I want to check if any of the word in array is present in the hash then return true. Json format can be different. Please help me how can i search certains words in a hash. Thanks in advance.
Upvotes: 3
Views: 603
Reputation: 11196
I think you just want to find if the data contains any of a list of words? If so
h = #your data set as posted so I won't put it here again
["Walmart","Optical","Anker"].select{|w| h.to_s.include?(w) } # shows which words were found.
["Walmart","Optical","Anker"].any?{|w| h.to_s.include?(w) } # returns bool
# => true
Pretty simple, I was thinking you needed something more complex. In this case convert the data hash to a string and see if the word is included in the string.
UPDATE:
Perhaps this is more idiomatic in Ruby version >= 2.3 you can dig but you still need to know the structure. @mudasobwa what do you recommend if structure is not reliable?
def deep_find_words(hash, words_to_match)
words =
hash.dig(:data, :Lines).map do |line|
line.dig(:Words).map do |word|
word.dig(:WordText)
end
end.flatten
words_to_match.select{|w| words.include? w}
end
deep_find_words(h, ["Walmart","Optical","Anker"])
Upvotes: 1