我有以下Ruby代码,它使用不同的参数多次调用同一函数,并将结果压入一个公共数组。
people_relations = []
people.zip(people_addresses).map do |person, address|
people_relations.push(createRelation(person, address))
end
people.zip(people_ph_numbers).map do |person, phone_number|
people_relations.push(createRelation(person, phone_number))
end
people.zip(people_aliases).map do |person, _alias|
people_relations.push(createRelation(person, _alias))
end
def createRelation(e1, e2)
[true, false].sample ? CurrentRelation.new(e1, e2) : PastRelation.new(e1, e2)
end
这段代码可以很好地工作,但是我觉得这不是Ruby惯用的方式,可以通过将代码压缩成更少的行或使其看起来更简洁来改进。
是否有更好的方法编写上面显示的代码?
答案 0 :(得分:2)
您可以创建一个包含将要使用的所有人员“属性”的数组,并使用Enumerable#each_with_object
可以分配一个初始数组,以填充每次对createRelation()的调用的结果:< / p>
attributes = [people_addresses, people_ph_numbers, people_aliases]
relations = people.each_with_object([]).with_index do |(person, memo), index|
attributes.each do |attribute|
memo << createRelation(person, attribute[index])
end
end
答案 1 :(得分:1)
为此,我可能会使用transpose
-> flat_map
解决方案,例如:
def CreateRelation(person, relationship)
if [true, false].sample
"#{person} is currently related to #{relationship}"
else
"#{person} used to be related to #{relationship}"
end
end
people = ['Person 1', 'Person 2', 'Person 3']
addresses = ['Person 1 Address', 'Person 2 Address', 'Person 3 Address']
phone_numbers = ['Person 1 Phone', 'Person 2 Phone', 'Person 3 Phone']
aliases = ['Person 1 AKA', 'Person 2 AKA', 'Person 3 AKA']
我们可以将这4个数组粘贴到单个数组中,然后transpose
,这样每个数组的第一个元素就彼此以数组结尾,第二个元素以另一个数组结尾,最后一个以三分之一结尾:< / p>
[people, addresses, phone_numbers, aliases].transpose # => [
# ["Person 1", "Person 1 Address", "Person 1 Phone", "Person 1 AKA"],
# ["Person 2", "Person 2 Address", "Person 2 Phone", "Person 2 AKA"],
# ["Person 3", "Person 3 Address", "Person 3 Phone", "Person 3 AKA"]]
,然后您可以通过致电flat_map
CreateRelation
:
result = [people, addresses, phone_numbers, aliases].transpose.flat_map do |person, *relations|
relations.map { |relationship| CreateRelation(person, relationship) }
end
#["Person 1 used to be related to Person 1 Address",
# "Person 1 used to be related to Person 1 Phone",
# "Person 1 used to be related to Person 1 AKA",
# "Person 2 is currently related to Person 2 Address",
# "Person 2 used to be related to Person 2 Phone",
# "Person 2 is currently related to Person 2 AKA",
# "Person 3 is currently related to Person 3 Address",
# "Person 3 used to be related to Person 3 Phone",
# "Person 3 used to be related to Person 3 AKA"]
或者,如果您不想map
/ flat_map
,那么在那一点上,您可以坚持迭代和推送。
我考虑得越多,我就越倾向于使用transpose
-> each_with_object
,而不是flat_map
...更少“创建一个数组然后抛出”,尽管我将其保留在flat_map
中,因为它是另一种选择,并且@Sebastian Palma已涵盖each_with_object
。