Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ruby中对哈希数组进行排序_Ruby_Sorting - Fatal编程技术网

在ruby中对哈希数组进行排序

在ruby中对哈希数组进行排序,ruby,sorting,Ruby,Sorting,我有一个哈希数组,如下所示: ward = {id: id, name: record["Externalization"], mnemonic: record["Mnemonic"], seqno: record["SeqNo"]} 所有字段都是字符串 现在我想先按序号排序,然后按名称排序。seqno可以为零(如果seqno为零,则该病房必须位于具有seqno的病房之后) 到目前为止,我得到的是: wardList.sort! do |a,b| return (a[:name]

我有一个哈希数组,如下所示:

ward = {id: id, name: record["Externalization"], mnemonic: record["Mnemonic"],
   seqno: record["SeqNo"]}
所有字段都是字符串

现在我想先按序号排序,然后按名称排序。seqno可以为零(如果seqno为零,则该病房必须位于具有seqno的病房之后)

到目前为止,我得到的是:

wardList.sort! do |a,b| 
  return (a[:name] <=> b[:name]) if (a[:seqno].nil? && b[:seqno].nil?) 
  return -1 if a[:seqno].nil?
  return 1 if b[:seqno].nil?
  (a[:seqno] <=> b[:seqno]).nonzero? ||
    (a[:name] <=> b[:name])
end
wardList.sort!做什么
如果(a[:seqno].nil?&&b[:seqno].nil?)返回(a[:name]b[:name])
如果是[:seqno].nil,则返回-1?
如果b[:seqno].nil,则返回1?
(a[:序号]b[:序号])非零||
(a[:名称]b[:名称])
结束
但这给了我一个错误:无法将符号转换为整数

这应该可以:

sorted = wardList.sort_by{|a| [a[:seqno] ? 0 : 1, a[:seqno], a[:name]] }
或对于某些红宝石(例如1.8.7):

首先,规范化数据,此处不能将整数作为字符串使用:

wardList = wardList.map { |x| x.merge({:id    => x[:id].to_i, 
                                       :seqno => x[:seqno].try(:to_i) }) }
然后您可以使用支持词典排序的
sort\u by

wardList.sort_by! { |x| [x[:seqno] || Float::INFINITY, x[:name]] }
例如:

irb(main):034:0> a = [{:seqno=>5, :name=>"xsd"}, 
                      {:seqno=>nil, :name=>"foo"}, 
                      {:seqno=>nil, :name=>"bar"}, 
                      {:seqno=>1, :name=>"meh"}]
irb(main):033:0> a.sort_by { |x| [x[:seqno] || Float::INFINITY, x[:name]] }
=> [{:seqno=>1, :name=>"meh"},
    {:seqno=>5, :name=>"xsd"},
    {:seqno=>nil, :name=>"bar"},
    {:seqno=>nil, :name=>"foo"}]

我认为您不应该在这里使用
return
,它会导致块返回到迭代器,迭代器返回到封闭方法,封闭方法返回到其调用方。改为使用
next
,这只会导致块返回迭代器(
sort!
在本例中),并执行如下操作:

wardList.sort! do |x,y|
  next  1 if x[:seqno].nil?
  next -1 if y[:seqno].nil?
  comp = x[:seqno] <=> y[:seqno]
  comp.zero? ? x[:name] <=> y[:name] : comp
end
wardList.sort!do | x,y|
下一个1如果x[:seqno].nil?
如果y[:seqno].nil,则next-1?
comp=x[:seqno]y[:seqno]
公司零?x[:名称]y[:名称]:公司
结束

是的,但如果[:seqno]为零怎么办?@Lieven,为什么?如何将一个数字与
nil
进行比较?设置一个默认值来解决这个问题是很自然的。@Lieven:所以现在你有两个单线解决方案来解决这个问题,非常简单和优雅。祝贺你。@Lieven:你似乎对你正在使用的工具缺乏一些基本的了解。查看我的答案,了解如何正确转换数据的示例。@Lieven:Ruby中的值
false
nil
被认为是布尔值false。因此,如果第一个操作数为
nil
,则第二个操作数甚至不会求值。顺便说一句,表达式不会返回
false
,它会返回第一个falsy值(
nil
)。经过编辑,应该包括您需要的内容首先在
nil?
状态下排序
:seqno
(因为字符串-'false'将始终位于'true'之前),然后在
:seqno
上排序,然后打开
:name
伟大的解决方案。但是当[:seqno]为nil时,它为什么不会崩溃呢?sort_by使用元组比较,而不是标准的排序比较。显然,元组被允许包含nil(但不是
true
false
),尽管我自己不确定比较实现实际上是如何做到这一点的
nil
通常会在non-nil之前,这就是为什么我们需要首先对nil状态进行排序哦,顺便说一下,回顾一下这个问题,它应该是
a[:seqno]?0:1
如果
x[:seqno].nil?&&,则给出错误的结果!y[:seqno].nil?
wardList.sort! do |x,y|
  next  1 if x[:seqno].nil?
  next -1 if y[:seqno].nil?
  comp = x[:seqno] <=> y[:seqno]
  comp.zero? ? x[:name] <=> y[:name] : comp
end