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:应该从子数组返回最大值数组的递归函数的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何根据枚举哈希对数组进行排序并返回 Ruby 中的最大值?

从分层数组Ruby生成平面数组的递归函数[关闭]

通过递归分而治之的数组中的最大数字

这个 ruby​​ 代码算作递归函数吗?

在 Ruby 中从多维数组创建排列

在 Ruby 中从多维数组创建排列