“自然的”在 Ruby 中对哈希数组进行排序
对于对哈希数组进行排序和自然排序,但是最好的方法是什么同时做两个?
my_array = [ {"id":"some-server-1","foo":"bar"},{"id":"some-server-2","foo":"bat"},{"id":"some-server-10","foo":"baz"} ]
我想对“id”进行排序,最终的排序是:
some-server-1
some-server-2
some-server-10
我觉得必须有一种聪明而有效的方法来做到这一点,尽管我个人不需要打破任何速度记录,只会对一些进行排序一百项。我可以在 sort_by 中实现比较函数吗?
There are workable answers for sorting an array of hashes and for natural sorting, but what is the best way to do both at once?
my_array = [ {"id":"some-server-1","foo":"bar"},{"id":"some-server-2","foo":"bat"},{"id":"some-server-10","foo":"baz"} ]
I would like to sort on "id" such that the final ordering is:
some-server-1
some-server-2
some-server-10
I feel like there must be a clever and efficient way to do this, though personally I don't need to break any speed records and will only be sorting a few hundred items. Can I implement a comparison function in sort_by?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,您的
my_array
是 JavaScript/JSON,所以我假设您确实有这个:那么您只需要
sort_by
'id'
值的数字后缀:如果“some-server-”前缀并不总是“some-server-”,那么您可以尝试这样的操作:
这会将
'id'
值拆分为数字和非数字部分,将数字片段与整数,然后使用数组<=>
运算符(按组件进行比较);只要数字和非数字组件始终匹配,这就会起作用。这种方法可以处理这个问题:但不是这个问题:
如果您需要处理最后一种情况,那么您需要手动逐项比较数组,并根据您所拥有的内容调整比较。您仍然可以获得
sort_by
Schwartzian Transform 类似这样的东西(没有经过很好测试的代码):这里的基本思想是推动比较噪声转移到另一个类,以防止
sort_by
退化为难以理解的混乱。然后我们使用与之前相同的扫描将字符串分成几部分并手动实现数组<=>
比较器。如果我们有同一类的两个事物,那么我们让该类的<=>
处理它,否则我们将两个组件强制为 String 并按原样比较它们。我们只关心第一个非0结果。First of all, your
my_array
is JavaScript/JSON so I'll assume that you really have this:Then you just need to
sort_by
the numeric suffix of the'id'
values:If the "some-server-" prefixes aren't always "some-server-" then you could try something like this:
That would split the
'id'
values into numeric and non-numeric pieces, convert the numeric pieces to integers, and then compare the mixed string/integers arrays using the Array<=>
operator (which compares component-wise); this will work as long as the numeric and non-numeric components always match up. This approach would handle this:but not this:
If you need to handle this last case then you'd need to compare the arrays entry-by-entry by hand and adjust the comparison based on what you have. You could still get some of the advantages of the
sort_by
Schwartzian Transform with something like this (not very well tested code):The basic idea here is to push the comparison noise off to another class to keep the
sort_by
from degenerating into an incomprehensible mess. Then we use the same scanning as before to break the strings into pieces and implement the array<=>
comparator by hand. If we have two things of the same class then we let that class's<=>
deal with it otherwise we force both components to String and compare them as such. And we only care about the first non-0 result.@mu 为我的情况提供了足够的答案,但我也弄清楚了引入任意比较的语法:
@mu gives a more than adequate answer for my case, but I also figured out the syntax for introducing arbitrary comparisons:
我认为如果您要对 id 字段进行排序,您可以尝试以下操作:
I think that if you are sorting on the
id
field, you could try this: