-1

I have a hash

my_hash = {"key1"=> {"key2"=> {"key3"=> "value"}}, "key4"=>  "value"}

I want to return only the full path of the keys as an array. All concatenated like this

[key1, key1key2, key1key2key3, key4].

Any suggestions on how to do this. Thanks

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
iyokeose
  • 1
  • 3
  • 2
    and what you try fo far? – inye Apr 05 '18 at 14:42
  • 2
    https://github.com/am-kantox/iteraptor – Aleksei Matiushkin Apr 05 '18 at 15:00
  • @mudasobwa: +1 for cool gem name. "meh" for method names. :) – Sergio Tulentsev Apr 05 '18 at 15:09
  • 1
    @SergioTulentsev it’s monkeypatching `Hash` and `Array`. I needed to be 102% sure there is no clash. In any case, in version `1.0` it’ll have a normal syntax with delegation via `hash.iteraptor_en.map {}`, `hash.iteraptor_es.mapa {}`, and `hash.iteraptor_ru.замаппить {}`. – Aleksei Matiushkin Apr 05 '18 at 15:37
  • 1
    @SergioTulentsev FWIW, it has the sibling for Elixir https://github.com/am-kantox/elixir-iteraptor – Aleksei Matiushkin Apr 05 '18 at 15:39
  • @mudasobwa: mind you, I don't have better name suggestions. But it should be _something_ in english. I don't know about you, but switching languages every two words breaks reading flow for me ("wait, what language was that? Looked like spanish, but I'm not sure. I need to go back and re-read."). While I smile at замаппить, it's even worse. Barely better than string of emoji :) – Sergio Tulentsev Apr 05 '18 at 15:44
  • @mudasobwa: yep, that delegation looks nice! – Sergio Tulentsev Apr 05 '18 at 15:46
  • Speaking of strange method names: [`Sidekiq.❨╯°□°❩╯︵┻━┻`](https://github.com/mperham/sidekiq/blob/873f1df9e0171a6eb1f9e6f50152f78e045b6df5/lib/sidekiq.rb#L52) – Stefan Apr 05 '18 at 15:51
  • @Stefan I like (and use) [this](https://github.com/mperham/sidekiq/blob/2ed92600fa71a9c275189d01df369ad4f8b9ca32/lib/sidekiq/api.rb#L279). – Aleksei Matiushkin Apr 05 '18 at 16:00
  • @SergioTulentsev https://github.com/am-kantox/iteraptor#boring-for-users-who-are-too-conservative thanks for pinging me for doing that :) – Aleksei Matiushkin Apr 06 '18 at 08:06
  • @mudasobwa: Much better – Sergio Tulentsev Apr 06 '18 at 08:08

2 Answers2

0

I've been able to solve this with the iteraptor helpers suggested by this user. Thanks

I used the feature 'aplanar' i.e

hash.aplanar.keys

returns the paths of all the keys that have values. Just as I wanted.

dinjas
  • 2,115
  • 18
  • 23
iyokeose
  • 1
  • 3
0

The following is a recursive method that progressively modifies the keys of inner hashes. For example,

{"key2"=> {"key3"=> "value"}}

is changed to

{"key1key2"=> {"key3"=> "value"}}

after which

{"key3"=> "value"}

is changed to

{"key1key2key3"=> "value"}

This allows me to simply accumulate the keys of these hashes.

def recurse(h)
  h.map do |k,v|
    next k unless v.is_a?(Hash)
    key, val = v.flatten
    [k, recurse("#{k}#{key}"=>val)]
  end.flatten
end

recurse my_hash
  #=> ["key1", "key1key2", "key1key2key3", "key4"]
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • I always try to avoid the use of the method `Array#flatten`, simply because I find it ugly. I welcome suggestions for how I can do away with it here. Changing `map` to `flat_map` is not sufficient. – Cary Swoveland Apr 05 '18 at 18:49