1

I want to transform the given array into result array:

given = [{
  "foo_v1_4" => [{
    "derivate_version" => 0,
    "layers" => {
      "tlayer" => {
        "baz" => {
          "three" => 0.65
        },
        "bazbar" => {
          "three" => 0.65
        }
      }
    }
  }]
}]


# the value of key :one is first hash key (foo_v1_4) plus underscore (_) plus derivate_version (0)
result = [{
    one: 'foo_v1_4_0',
    tlayer: 'baz',
    three: '0.6'
  },
  {
    one: 'foo_v1_4_0',
    tlayer: 'bazbar',
    three: '0.6'
  }
]

What I tried:

given.each do |el |

    el.each do |derivat |
      derivat.each do |d |
        d.each do |layer |
          layer.each do |l |
            derivat = "#{d}_#{l['derivate_version']}"
          puts derivat
        end
      end
    end
  end

end

I'm struggling at iterating through "layers" hash, the amount of elements in layers is equal to the amount of elements in result array.

1
  • Your post is already tagged with ruby so there's no need to have "Ruby: " in your post title. Commented Aug 27, 2020 at 16:58

2 Answers 2

4

It helps to format the objects so we can better see their structures:

given = [
  {
    "foo_v1_4" => [
      { "derivate_version" => 0,
        "layers" => {
          "tlayer" => {
            "baz" => { "three" => 0.65 },
            "bazbar" => { "three" => 0.65 }
          }
        }
      }
    ]
  }
]
result = [
  {
    one: 'foo_v1_4_0',
    tlayer: 'baz',
    three: '0.6'
  },
  {
    one: 'foo_v1_4_0',
    tlayer: 'bazbar',
    three: '0.6'
  }
]

We can begin by writing the structure of result:

result = [
  {
    one: 
    tlayer:
    three:
  },
  {
    one: 
    tlayer:
    three:
  }
]

We see that

given = [ { "foo_v1_4" => <array> } ]

The values of the keys :one in the hash result[0] is therefore the first key of the first element of given:

one_val = given[0].keys[0] 
  #=> "foo_v1_4"

result = [
  {
    one: one_val
    tlayer:
    three:
  },
  {
    one: one_val
    tlayer:
    three:
  }
]

All the remaining objects of interest are contained in the hash

h = given[0]["foo_v1_4"][0]["layers"]["layer"]
  #=> {
  #     "baz"=>{ "three"=>0.65 },
  #     "bazbar"=>{ "three"=>0.65 }
  #   }

so it is convenient to define it. We see that:

h.keys[0]
  #=> "baz"
h.keys[1]
  #=> "bazaar"
h["bazbar"]["three"]
  #=> 0.65

Note that it generally is not good practice to assume that hash keys are ordered in a particular way.

We may now complete the construction of result,

v = h["bazbar"]["three"].truncate(1)
  #=> 0.6

result = [
  {
    one: one_val,
    tlayer: h.keys[0],
    three: v
  },
  { one: one_val,
    tlayer: h.keys[1],
    three: v
  }
]
  #=> [
  #     { :one=>"foo_v1_4", :tlayer=>"baz",    :three=>0.6 },
  #     { :one=>"foo_v1_4", :tlayer=>"bazbar", :three=>0.6 }
  #   ]

The creation of the temporary objects one_val, h, and v improves time- and space-efficiency, makes the calculations easier to test and improves the readability of the code.

Sign up to request clarification or add additional context in comments.

Comments

1

Try the below:

result = []
given.each do |level1|
  level1.each do |key, derivate_versions|
    derivate_versions.each do |layers|
      # iterate over the elements under tlayer
      layers.dig('layers', 'tlayer').each do |tlayer_key, tlayer_value|
        sub_result = {}
        # key - foo_v1_4, layers['derivate_version'] - 0 => 'foo_v1_4_0'
        sub_result[:one] = key + '_' +  layers['derivate_version'].to_s
        # talyer_key - baz, barbaz
        sub_result[:tlayer] = tlayer_key
        # talyer_value - { "three" => 0.65 }
        sub_result[:three] = tlayer_value['three']
        result << sub_result
      end
    end
  end
end

The value of result will be:

2.6.3 :084 > p result
[{:one=>"foo_v1_4_0", :tlayer=>"baz", :three=>0.65}, {:one=>"foo_v1_4_0", :tlayer=>"bazbar", :three=>0.65}]

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.