在Ruby中对数组数组进行排序

Tyl*_*r K 22 ruby arrays

我有一个像这样的数组:

irb(main):028:0> device_array
=> [["name1", "type1", ["A", "N", "N"], ["Attribute", "device_attribute"], 9], ["name2","type2", ["A", "N", "N"], ["Attribute", "device_attribute"], 7]]
Run Code Online (Sandbox Code Playgroud)

我想在第4个元素上对整个device_array进行排序.

我试过了

AllDevicesController.all_devices.sort do | a,b |
  for i in 0..(AllDevicesController.all_devices.length - 1) do
    a[i][4] <=> b[i][4]
  end
end
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

AllDevicesController.all_devices.sort do | a,b |
  a[][4] <=> b[][4]
end
Run Code Online (Sandbox Code Playgroud)

这两种方法都没有奏效.

我使用它作为参考:http: //ariejan.net/2007/01/28/ruby-sort-an-array-of-objects-by-an-attribute/

我想我错过了一些红宝石,这让我很容易.

Sin*_*our 29

您不能使用<=>nil.

你的代码应该是这样的:

AllDevicesController.all_devices.sort do |a, b|
  a[4].nil? ? -1 : b[4].nil? ? 1 : a[4] <=> b[4]
end
Run Code Online (Sandbox Code Playgroud)

这将把没有索引元素4的子数组放在结果的开头.各地要做到这一点的其他方式,换-11.

您也可以使用sort_by而不是sort.我认为这已经在Ruby 1.8.7中引入了(因此如果您使用的是旧版本,它可能不起作用).它类似于:

AllDevicesController.all_devices.sort_by { |e| e.nil? ? 0 : e[4] }
Run Code Online (Sandbox Code Playgroud)

这将处理没有第4个元素的子数组,就像它是0.更改此常量以适合您.

编辑:

调整输入后,现在很清楚你是非常接近正确的答案.你的代码应该是:

AllDevicesController.all_devices.sort do |a, b|
  a[4] <=> b[4]
end
Run Code Online (Sandbox Code Playgroud)

或者简单(假设Ruby 1.8.7或更高版本):

AllDevicesController.all_devices.sort_by { |e| e[4] }
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,变量ab将包含原始数组的元素,这就是为什么你可以直接在任何位置访问一个元素(你不需要像a[][4],这是不正确的Ruby语法).


Mar*_*ark 9

sort_by

<=>尝试使用飞船运算符 ( )而不是sort_by

device_array.sort_by { |el| el[4] }
Run Code Online (Sandbox Code Playgroud)

虽然如果你知道第四个元素是最后一个,你也可以el.last在块中使用。

Ruby 文档:Enumerable#sort_by