比flat_map更好的方式来迭代数据结构

时间:2015-03-30 00:45:24

标签: ruby

我有一个用户数组,每个用户都会响应一个名为“房屋”的方法来返回用户的所有房屋。我希望有一个带有用户名的哈希数组和颜色名称,所以这就是我所拥有的:

[user1, user2, user3].flat_map do |user|
  user.houses.map do |house|
    create_user_house(user, house)
  end
end

def create_user_house(user, house)
  {name: user.name, house: find_color(house)}
end

有没有更好的方法呢?我觉得在这种情况下使用flat_map可能会有点过分

实施例

说我有两个用户:

user_1 which name is 'John'
user_1 has two houses: house_1 and house_2
user_2 which name is 'Steve'
user_2 has one house: house_3

预期结果应为:

[{name: 'John', house_color: find_color(house1)}, {name: 'John', house_color: find_color(house2)}, {name: 'Steve', house_color: find_color(house3)}]

1 个答案:

答案 0 :(得分:1)

让我们有一些数据可供使用:

class User
  attr_accessor :name, :houses
  def initialize name, houses
    @name   = name
    @houses = houses
  end
end

wilma = User.new 'Wilma', [:bungalow, :cottage]
hank  = User.new 'Hank',  [:cape_cod, :bungalow]
oaf   = User.new 'Oaf',   [:shed,     :cottage]

def find_color(h)
  case h
  when :bungalow then :yellow
  when :cottage  then :blue
  when :cape_cod then :white
  when :shed     then :black
  end
end

你的方法很好,但我不确定你需要单独的方法。没有它,它是:

[wilma, hank, oaf].flat_map do |user|
  user.houses.map { |h| { name: user.name, house_color: find_color(h) } }
end
  #=> [{:name=>"Wilma", :house_color=>:yellow},
  #    {:name=>"Wilma", :house_color=>:blue},
  #    {:name=>"Hank",  :house_color=>:white},
  #    {:name=>"Hank",  :house_color=>:yellow},
  #    {:name=>"Oaf",   :house_color=>:black},
  #    {:name=>"Oaf",   :house_color=>:blue}] 

我认为flat_map非常合适。

你可以用很多其他方式写出来,当然,其中一个是:

[wilma, hank, oaf].each_with_object([]) do |user, a|
  user.houses.each { |h| a << { name: user.name, house_color: find_color(h) } }
end