排序阵列的Ruby中的阵列

问题描述 投票:22回答:4

我有像这样数组的数组:

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

我想,第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

我也试过:

AllDevicesController.all_devices.sort do | a,b |
  a[][4] <=> b[][4]
end

这两种方法都没有奏效。

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

我想我想的东西rubyish使这很容易。

ruby arrays
4个回答
29
投票

你不能<=>使用nil

你的代码应该是这样的:

AllDevicesController.all_devices.sort do |a, b|
  a[4].nil? ? -1 : b[4].nil? ? 1 : a[4] <=> b[4]
end

这将使子阵,在结果的开始没有索引4的元素。要做到这一点的其他方式,交换-11

你也可以使用sort_by代替sort的。我觉得这已经用Ruby 1.8.7(因此,如果您使用的是旧版本可能无法正常工作)被引入。它会是这样的:

AllDevicesController.all_devices.sort_by { |e| e.nil? ? 0 : e[4] }

这将把子阵,无4元,如果它是0更改此常量适合你。

编辑:

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

AllDevicesController.all_devices.sort do |a, b|
  a[4] <=> b[4]
end

或简单的(假设的Ruby 1.8.7或以上):

AllDevicesController.all_devices.sort_by { |e| e[4] }

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


4
投票

sort_by

除了使用飞船运营商(<=>)的试用一下sort_by

device_array.sort_by { |el| el[4] }

但如果你知道第四个要素是最后一个,你可以在块也使用el.last

Ruby的文档:Enumerable#sort_by


2
投票

第四元素实际上是在指数3,这意味着你会做这样的:

all_devices.sort do |a, b|
  a[3] <=> b[3]
end

如果你真的想在指数4(不用于all_devices的第一个元素存在)的元素进行排序,那么你需要先添加相比,NilClass:

class NilClass
  def <=> (other)
    1
  end
end

all_devices.sort do |a, b|
  a[4] <=> b[4]
end

这将排序nil到底。 <=>的返回值更改为-1到排序他们前面。


2
投票

我知道这个问题已经回答了,我不会现在要解决这个问题,但..

你确定一个数组将是数据最适合?我说的是这些数据元素:[ “NAME1”, “类型1”,[ “A”, “N”, “N”],[ “属性”, “device_attribute”],9]

似乎是一个Struct什么可能是更合适和可管理的这一点,那么你可以有结构的数组。只是一个想法。

© www.soinside.com 2019 - 2024. All rights reserved.