在sort块中使用elsif的问题

时间:2019-01-23 21:13:52

标签: ruby

我有这个数组:

ary = [[1, 6, 7], [1, 4, 9], [1, 8, 3]]

我想按每个子数组中的第一个奇数或最后一个数字(如果它们全为偶数)对其进行排序。

由于对于这个特定的1,每个数组中的第一个元素都是相同的对象ary,所以我可以这样解决:

ary2 = ary.sort_by { |a, b, c| b.odd? ? b : c }

但是当我尝试更通用的方法时:

arr2 = ary.sort_by { |a, b, c| a.odd? ? a : b.odd? ? b : c }

ary2未分类返回。

我试图删除像这样的三元运算符:

ary2 = ary.sort_by do |a, b, c|
  if a.odd? 
    a
  elsif b.odd?
    b
  else
    c
  end
end

具有相同的效果(即无效果)。

是否由于某些原因不能在传递给elsif方法的块中使用sort_by


编辑:Axiac指出了我的逻辑问题。看来条件逻辑必须处理奇数和偶数值的所有可能排列。这有效:

arr2 = arr.sort_by do |a, b, c| 
  if a.odd?
    if b.odd?
      if c.odd?
        [a, b, c]
      else
        [a, b]
      end
    elsif c.odd?
      [a, c]
    else
      a
    end
  elsif b.odd?
    if c.odd?
      [b, c]
    else
      b
    end
  else
    c
  end
end

也许有一种更简洁,更不那么脆弱的方法,但是以这种方式来做可能是一个好主意:

arr2 = arr.sort_by do |sub_arr|
  temp = sub_arr.select do |e|
    e.odd?
  end
  temp.empty? ? Array(sub_arr.last) : temp
end

我会出来的。

2 个答案:

答案 0 :(得分:2)

我发现问题的陈述含糊。我将给出一个解释,它包含一种解释。如果那不是您想要的,请澄清问题。

def my_sort(arr)
  arr.sort_by {|a| a.any?(&:odd?) ? a.map {|e| e.odd? ? e : Float::INFINITY} : [a.last]}
end

my_sort [[1, 6, 7], [1, 4, 9], [1, 2, 3]]
  #=>   [[1, ∞, 7], [1, ∞, 9], [1, ∞, 3]] (sort_by)
  #=>   [[1, 2, 3], [1, 6, 7], [1, 4, 9]]
my_sort [[3, 6, 7], [4, 1, 9], [5, 8, 1]]
  #=>   [[3, ∞, 7], [∞, 1, 9], [5, ∞, 1]] (sort_by) 
  #=>   [[3, 6, 7], [5, 8, 1], [4, 1, 9]] 
my_sort [[2, 6, 8], [4, 1, 4], [8, 6, 2]]
  #=>   [[8],       [∞, 1, ∞], [2]]       (sort_by) 
  #=>   [[8, 6, 2], [2, 6, 8], [4, 1, 4]] 
my_sort [[8, 6, 2], [5, 1, 1], [6, 8, 4]]
  #=>   [[2],       [5, 1, 1], [4]        (sort_by) 
  #=>   [[8, 6, 2], [6, 8, 4], [5, 1, 1]] 

对于每个示例,我都显示了sort_by使用的数组来产生下一行所示的排序。

答案 1 :(得分:2)

关于您的原始问题,正如axiac在注释中指出的那样,排序的结果应与输入数组完全相同,因为它们全部由每个子数组中的第一个奇数元素({{1 }},并且该排序方法在MRI中是稳定的。


关于编辑后的问题,我的答案是:

1

我非常有信心这就是您在完成所需编辑后所写的内容,但是我不确定这是否是您想要的,因为排序机制对我来说很奇怪。