新手问题 case when 生成 hash .这样的代码能再优化嘛?

luffycn · 2014年12月09日 · 最后由 davidhuangdw 回复于 2014年12月09日 · 1606 次阅读
def hello

  final_hash = Hash.new

  list.each do |properties|

    properties_name = properties.name

    case properties.format
    when :a
      final_hash[properties_name] = 'xxx'
    when :b
      final_hash[properties_name] = 'yyy'
    when :c

      final_hash[properties_name] = 'zzz'

    end

  end

  final_hash

end

这样的代码有办法变得更好看点嘛?

properties_hash = {:a => 'xxx', :b => 'yyy', :c => 'zzz'} final_hash[properties_name] = properties_hash[properties.format]

def hello
  TABLE = {a: 'xxx', b: 'yyy', c: 'zzz'}

  property_list = list.map do |property|
    [property.name, TABLE[property.format]]
  end

  Hash[property_list]
end
  1. 把逻辑中属于数据的部分抽取出来,以后添加或修改也容易。
  2. map 替代 each 的操作,让代码更像函数式。
  3. 非常神奇的 Hash::[] 方法,我也是刚查到的,感觉方法名不太好。
  4. 块的参数用单数形式貌似更贴切。
3 楼 已删除
4 楼 已删除
table = {a: 'xxx', b: 'yyy', c: 'zzz'}
final_hash = Hash.new
list.each do |properties|
   next unless (v = table[properties.format] )
   final_hash[properties.name] = v
end

@small_fish__ @yuhaidonghd 这些方式都很棒,问题点在于,我的这个 table 的值是不确定的,可能是 a: 'xxx', b: 'yyy' 也可能没有 a, b 只有 c,或者可能有 a, b, c, d, e 更多

呵呵,如果不介意逻辑太散,可以多重构一点,把逻辑都分开:

#假设,输入是这样:
require 'ostruct'
def list
  @list ||= [
    {name:'tom', format: :a},
    {name:'bob', format: :b},
    {name:'dav', format: :c}
  ].map{|v| OpenStruct.new(v)}
end

# 那么:
def rule
  @rule ||= {a:'xxx', b:'yyy', c:'zzz'}
end
def parse_format(format)
  rule[format]
end
def info_from_item(item)
  {item.name => parse_format(item.format)}
end

def hello
  list.map(&method(:info_from_item)).reduce({},&:merge)
end
p hello

# 如果要加情况就:
rule.merge!(new_format: new_info)
```ruby
需要 登录 后方可回复, 如果你还没有账号请 注册新账号