0

我有一大堆哈希:

array = [
  {color: '5 absolute', ... },
  {color: '5.0', ... },
  {color: '5.1', ... },
  {color: 'last', ... },
  {color: '50', ... },
  {color: '5 elite', ... },
  {color: 'edge'}
]

我需要订购颜色:

5 absolute
5 elite
5.0
5.1
50
edge
last

优先级是:

first going spaces ' ',
then dots '.',
then digits '7',
then other 'string'

这就像SQL activerecord 模拟查询,但我不希望在后台进行那种困难的查询。我想要这个逻辑。如何使用 AR 查询来做到这一点?

4

3 回答 3

1

您总是可以对哈希数组进行排序。

array.map{|h| h[:color]}.sort
=> ["5 absolute", "5 elite", "5.0", "5.1", "50", "edge", "last"]

以下首先按数字排序,然后按数字后面的字符串排序。

array = [{color: '5 absolute'}, {color: '5.0'}, {color: '5.1'}, 
         {color: 'last'}, {color: '50'}, {color: '5 elite'}, 
         {color: 'edge'}, {color: '6 absolute'}, {color: '7'}]

array.map{|h| h[:color]}.sort_by do |s|
  n = s.to_f
  if n == 0 && s.match(/\d/).nil?
    n = Float::INFINITY
  end
  [n, s.split(" ")[-1]]
end
=> ["5.0", "5 absolute", "5 elite", "5.1", "6 absolute", "7", "50", "edge", "last"]
于 2013-11-11T10:39:16.087 回答
0

从你的问题很难说出你想要什么。特别是因为您要求的顺序与正常排序创建的顺序完全相同。

无论如何,这是一种按照您想要的方式创建“自定义排序”顺序的方法。这与常规排序之间的区别在于,在这种排序中,可以使某些类型的字符或字符集胜过其他类型。

array = [
  {color: '5 absolute'},
  {color: '5.0'},
  {color: '50 hello'},
  {color: 'edge'}
]
p array.sort_by{|x| x[:color]} #=> [{:color=>"5 absolute"}, {:color=>"5.0"}, {:color=>"50 hello"}, {:color=>"edge"}]
# '50 hello' is after '5.0' as . is smaller than 0.

解决这个问题有点棘手,我会这样做:

# Create a custom sort order using regexp:
# [spaces, dots, digits, words, line_endings]
order  = [/\s+/,/\./,/\d+/,/\w+/,/$/]

# Create a union to use in a scan:
regex_union = Regexp.union(*order)

# Create a function that maps the capture in the scan to the index in the custom sort order:
custom_sort_order = ->x{
 x[:color].scan(regex_union).map{|x| [order.index{|y|x=~y}, x]}.transpose
}

#Sort:
p array.sort_by{|x| custom_sort_order[x]}
# => [{:color=>"5 absolute"}, {:color=>"50 hello"}, {:color=>"5.0"}, {:color=>"edge"}]
于 2013-11-11T11:55:00.530 回答
0

像这样?

h = [{:color=>"5 absolute"},
 {:color=>"5.0"},
 {:color=>"5.1"},
 {:color=>"last"},
 {:color=>"50"},
 {:color=>"5 elite"},
 {:color=>"edge"}]

h.map(&:values).flatten.sort
# => ["5 absolute", "5 elite", "5.0", "5.1", "50", "edge", "last"]

或所有其他答案...

于 2013-11-11T10:27:26.757 回答