Ruby:应该从子数组返回最大值数组的递归函数的问题
Posted
技术标签:
【中文标题】Ruby:应该从子数组返回最大值数组的递归函数的问题【英文标题】:Ruby: Issue with Recursive Function that Should Return Array of Max Values from Sub-arrays 【发布时间】:2017-01-28 02:45:35 【问题描述】:下面的函数被设计成接受一个数组数组并返回其子数组的最大值。
def temp(list)
if list.all? |i| i.kind_of?(Array)
return(list.each |j| j.max )
else
return(list)
end
end
所以给定一个这样的列表和函数调用:
x = [[1, 2], [3, 4]]
temp(x)
它应该返回 [2, 4],但它只返回原始数组 [[1, 2], [3, 4]]。我想知道这里出了什么问题。
谢谢
【问题讨论】:
如果他们对处理混合数组很酷,我们甚至可以将其进一步简化为list.map |each| [*each].max
。我认为他们可能是。
【参考方案1】:
each
对数组的每个元素进行操作,然后返回(原始)数组。你要的方法是map
:
def temp(list)
if list.all? |i| i.kind_of?(Array)
list.map |j| j.max
else
list
end
end
x = [[1, 2], [3, 4]]
temp(x)
# => [2, 4]
然而,显式类型检查在 Ruby 中不是惯用的,它更喜欢使用鸭子类型。不要检查i
是否是一个数组;只需检查它是否响应max
:
def temp(list)
return list unless list.all? |i| i.respond_to?(:max)
list.map(&:max)
end
【讨论】:
您也可以使用list.map |l| l.send ( l.respond_to?(:max) ? :max : :itself )
来允许在同一级别混合数组和标量。
@MarkReed 或list.map |l| l.respond_to?(:max) ? l.max : l
。 ?
如果我们放宽了all?
的要求,你可以使用list.map |l| [*l].max
。
不,太清楚了。 list.map |l| l.send %imax itself.find |s| l.respond_to? s
怎么样 ;-)
public_send
优于 send
,不是吗?【参考方案2】:
如果您放宽all?
的要求,那么……
试试这个
def temp(list)
list.map |l| Array(l).max
end
这是如何工作的?
Array(l)
把数组变成数组
并将其他对象转换为单元素数组
并将nil
变成一个空数组
因此我们可以随时拨打max
【讨论】:
您通常应该更喜欢Array(l)
,它几乎不涉及偷听,而不是 [*l]
,这是一种将数组转换为自身的极其昂贵的方法,在功能上是无操作的。【参考方案3】:
在对列表的每个成员运行代码块后,您将返回列表本身。相反,您可以在函数中创建另一个列表,然后将 max
值推送到该列表中,然后返回它。
def temp(list)
if list.all? |i| i.kind_of?(Array)
maxlist=[]
list.each |j| maxlist << j.max
return maxlist
else
return(list)
end
end
x = [[1, 2], [3, 4]]
puts temp(x)
这将按预期输出 2 和 4。
【讨论】:
初始化一个空列表然后使用each
追加到它是非常不习惯的。 map
是你应该在这里使用的。
@meagar 当然!我对 Ruby 的经验还不是很丰富,只有在阅读了 Jordan 的回答后才想起这种方法。认为在它之后编辑我的不公平!以上是关于Ruby:应该从子数组返回最大值数组的递归函数的问题的主要内容,如果未能解决你的问题,请参考以下文章