def fruits_of_kind(kind)
return nil if kind.nil?
result = []
([] << kind).flatten.each{|k| result << basket.select{|f| f.fruit_type == k.to_s }}
result
end
'splat' 运算符可能是最好的方法,但有两件事需要注意:传入 nil 或列表。要针对您想要的输入/输出修改 Pesto 的解决方案,您应该执行以下操作:
def fruits_of_kind(*kinds)
return nil if kinds.compact.empty?
basket.select do |fruit|
kinds.flatten.each do |kind|
break true if fruit.fruit_type == kind.to_s
end == true #if no match is found, each returns the whole array, so == true returns false
end
end
如果传入 nil,* 会将其转换为 [nil]。如果要返回 nil 而不是空列表,则必须将其压缩(删除空值)为 [],然后如果为空则返回 nil。
如果您传入一个列表,例如 [:apple, 'banana'],* 会将其转换为 [[:apple, 'banana']]。这是一个细微的区别,但它是一个包含另一个列表的单元素列表,因此您需要在执行“每个”循环之前展平种类。展平会将其转换为 [:apple, 'banana'],就像您期望的那样,并为您提供您正在寻找的结果。
编辑:更好,感谢格雷格坎贝尔:
def fruits_of_kind(basket, kind)
return nil if kind.nil?
kind_list = ([] << kind).flatten.map{|kind| kind.to_s}
basket.select{|fruit| kind_list.include?(fruit) }
end
或(使用 splat)
def fruits_of_kind(*kinds)
return nil if kinds.compact.empty?
kind_list = kinds.flatten.map{|kind| kind.to_s}
basket.select{|fruit| kind_list.include?(fruit.fruit_type) }
end