-1

我写了一个快速方法来确认来自网页的数据是否正确排序:

def subsort_columns(*columns)
  columns.transpose.sort
end

这适用于基本测试。现在,已经引入了复杂的子排序,我很确定我仍然需要使用数组,因为不能保证散列以特定顺序返回。在这种情况下,输入的顺序表示子排序优先级。

# `columns_sort_preferences` is an Array in the form of:
# [[sort_ascending_bool, column_data]]
# i.e.
# subsort_columns([true, column_name], [false, column_urgency], [true, column_date])
# Will sort on name ascending, then urgency descending, and finally date ascending.
def subsort_columns(*columns_sort_preferences)

end

这就是我卡住的地方。我想干净地做到这一点,但除了为任何父排序上发生的每个子排序滚动一个循环之外,什么都想不出来……但这听起来是错误的。

随意提供更好的建议,因为我不依赖于这个实现。

下面是一些测试数据:

a =   [1,1,1,2,2,3,3,3,3]
b = %w(a b c c b b a b c)
c = %w(x z z y x z z y z)
subsort_columns([true, a], [false, b], [false, c])
=> [[1, 'c', 'z'], 
    [1, 'b', 'z'], 
    [1, 'a', 'x'], 
    [2, 'c', 'y'], 
    [2, 'b', 'x'], 
    [3, 'c', 'z'],
    [3, 'b', 'z'],
    [3, 'b', 'y'],
    [3, 'a', 'z']]

更新:

标记为重新打开,因为我在代码库中作为我自己的答案提供的函数上方的评论中链接到了这个问题。更不用说我从这里的答案中得到的帮助清楚地显示了我的问题的解决方案,我想赏金给我一个正确方向的提示。请不要删除这个问题,它对我很有帮助。如果您不同意,请至少发表评论,说明您不清楚的地方。

4

3 回答 3

2

使用排序 {|a, b| 块} → new_ary

a =   [1,1,1,2,2,3,3,3,3]
b = %w(a b c c b b a b c)
c = %w(x z z y x z z y z)
sorted = [a, b, c].transpose.sort do |el1, el2|
  [el1[0], el2[1], el2[2]] <=> [el2[0], el1[1], el1[2]] 
end

结果:

[[1, "c", "z"],
 [1, "b", "z"],
 [1, "a", "x"]
 [2, "c", "y"],
 [2, "b", "x"],
 [3, "c", "z"],
 [3, "b", "z"],
 [3, "b", "y"],
 [3, "a", "z"]]

对于降序列​​,反转 spaceship 运算符的左右元素。

于 2013-08-01T16:35:56.020 回答
0

一种方法是按相反的顺序进行一系列“稳定排序”。从内部排序开始,到外部排序。稳定性属性意味着内部排序顺序保持不变。

不幸的是,Rubysort不稳定。但是请参阅此问题以获取解决方法。

于 2013-08-01T15:30:47.043 回答
0
# Sort on each entry in `ticket_columns`, starting with the first column, then second, etc.
# Complex sorts are supported. If the first element in each `ticket_columns` is a true/false
# boolean (specifying if an ascending sort should be used), then it is sorted that way. 
# If omitted, it will sort all ascending.
def _subsort_columns(*ticket_columns)
  # Is the first element of every `ticket_column` a boolean?
  complex_sort = ticket_columns.all? { |e| [TrueClass, FalseClass].include? e[0].class }
  if complex_sort
    data = ticket_columns.transpose
    sort_directions = data.first
    column_data = data[1..-1].flatten 1
    sorted = column_data.transpose.sort do |cmp_first, cmp_last|
      cmp_which = sort_directions.map { |b| b ? cmp_first : cmp_last }
      cmp_these = sort_directions.map { |b| b ? cmp_last : cmp_first }
      cmp_left, cmp_right = [], []
      cmp_which.each_with_index { |e, i| cmp_left << e[i] }
      cmp_these.each_with_index { |e, i| cmp_right << e[i] }
      cmp_left <=> cmp_right
    end
    sorted
  else
    ticket_columns.transpose.sort
  end
end
于 2013-08-01T20:27:42.550 回答