user user - 5 months ago 14
Ruby Question

Replace hash value

I have an array of hashes:

[{"__content__"=>"Guitars", "id"=>"2"},
{"__content__"=>"For Guitars", "id"=>"3", "parentId"=>"2"},
{"__content__"=>"6-string", "id"=>"24", "parentId"=>"2"},
{"__content__"=>"7-string", "id"=>"25", "parentId"=>"2"},
{"__content__"=>"8-string", "id"=>"26", "parentId"=>"2"}]


I want to replace the
parentId
values with the
__content__
values to get:

[{"__content__"=>"Guitars", "id"=>"2"},
{"__content__"=>"For Guitars", "id"=>"3", "parentId"=>"Guitars"},
{"__content__"=>"6-string", "id"=>"24", "parentId"=>"Guitars"},
{"__content__"=>"7-string", "id"=>"25", "parentId"=>"Guitars"},
{"__content__"=>"8-string", "id"=>"26", "parentId"=>"Guitars"}]


How can I do it?

Answer

I prefer to change this nasted array to hash for better maping.

input

arr = [
  {"__content__" => "Guitars", "id" => "2"},
  {"__content__" => "For Guitars", "id" => "3", "parentId" => "2"},
  {"__content__" => "6-string", "id" => "24", "parentId" => "2"},
  {"__content__" => "7-string", "id" => "25", "parentId" => "2"},
  {"__content__" => "8-string", "id" => "26", "parentId" => "2"}
]

create parents

parents = arr.each_with_object({}) { |h, exp| exp[h['id']] = h['__content__'] }

After this good map structure you can use simply map method.

process

output = arr.map do |h|
  h['parentId'] = parents[h['parentId']] if h['parentId'] && parents[h['parentId']]
  h
end

output

p output

# [
#   {"__content__" => "Guitars", "id" => "2"},
#   {"__content__" => "For Guitars", "id" => "3", "parentId" => "Guitars"},
#   {"__content__" => "6-string", "id" => "24", "parentId" => "Guitars"},
#   {"__content__" => "7-string", "id" => "25", "parentId" => "Guitars"},
#   {"__content__" => "8-string", "id" => "26", "parentId" => "Guitars"}
# ]

I hope this helps.

EDIT

You can also use this way

sort by ID

arr.sort_by! { |h| h['id'] }

process

output = arr.each_with_object({}) do |h, exp|
    exp[h['id']] = h
    h['parentId'] = exp[h['parentId']]['__content__'] if h['parentId'] && exp[h['parentId']]
    h
  end

after this you will have hash with id like keys, so for your output:

output

p output.values

# [
#  {"__content__"=>"Guitars", "id"=>"2"},
#  {"__content__"=>"6-string", "id"=>"24", "parentId"=>"Guitars"},
#  {"__content__"=>"7-string", "id"=>"25", "parentId"=>"Guitars"}, 
#  {"__content__"=>"8-string", "id"=>"26", "parentId"=>"Guitars"},
#  {"__content__"=>"For Guitars", "id"=>"3", "parentId"=>"Guitars"}
# ]