简体   繁体   中英

Merging keys and values from hash in Ruby

I have a hash with the number of occurrences of cities from a model and I want to merge nil or blank keys and values into one and rename the new single key

for example

@raw_data = {nil => 2, "" => 2, "Berlin" => 1, "Paris" => 1}
# to
@corrected_data = {"undefined" => 4, "Berlin" => 1, "Paris" => 1}

I have looked into the merge method from the Rubydoc but it only merges if two keys are similar, but in this case nil and "" are not the same.

I could also create a new hash and add if nil or blank statements and add the values to a new undefined key, but it seems tedious.

I'd do :

@raw_data = {nil => 2, "" => 2, "Berlin" => 1, "Paris" => 1}
key_to_merge = [nil, ""]

@correct_data = @raw_data.each_with_object(Hash.new(0)) do |(k,v), out_hash|
  next out_hash['undefined'] += v if key_to_merge.include? k
  out_hash[k] = v
end

@correct_data # => {"undefined"=>4, "Berlin"=>1, "Paris"=>1}

Ruby cannot automatically determine what do you want to do with values represented by two "similar" keys. You have to define the mapping yourself. One approach would be:

def undefined?(key)
  # write your definition of undefined here
  key.nil? || key.length == 0
end

def merge_value(existing_value, new_value)
  return new_value if existing_value.nil?
  # your example seemed to add values
  existing_value + new_value
end

def corrected_key(key)
  return "undefined" if undefined?(key)
  key
end

@raw_data = {nil => 2, "" => 2, "Berlin" => 1, "Paris" => 1}

@raw_data.reduce({}) do |acc, h|
  k, v = h
  acc[corrected_key(k)] = merge_value(acc[corrected_key(k)], v)
  acc
end

# {"undefined" => 4, "Berlin" => 1, "Paris" => 1}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM