【发布时间】:2016-04-27 06:58:24
【问题描述】:
我正在处理一组数组。我需要对行进行排序,排序标准是从左到右依次为每列(从第 2 列开始)的值。 Nil 值必须被推到底部。一旦被推到底部,我需要保留 nil 列,因为它们没有连续的搜索改变它们相对于彼此的位置。从这个数组开始:
sort_array =
[[297, 100, 101, 235, 253, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil],
[256, 105, 111, 212, 216, 264, nil, nil],
[276, 108, 111, 204, 207, 257, 259, 367],
[274, 66, 66, 120, 121, nil, 150, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[283, 102, 106, 193, 199, 247, 248, 343]]
我用这些代码行遍历数组:
(1..sort_array[0].size - 1).each do |i|
sort_array.sort_by! { |e| [e[i] ? 0 : 1, e[i]] }
end
这个想法是忽略第一列,但按升序对第二列到第 n 列进行排序,将 nil 值推到底部。这给出了以下结果:
=> [[283, 102, 106, 193, 199, 247, 248, 343],
[276, 108, 111, 204, 207, 257, 259, 367],
[256, 105, 111, 212, 216, 264, nil, nil],
[297, 100, 101, 235, 253, nil, nil, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[274, 66, 66, 120, 121, nil, 150, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil]]
这与我需要的很接近,但并不完全正确。问题是一旦被推到底部的 nil 值就不会保持不变。例如,对第一个值为 247 的列进行排序后,数组将如下所示:
=> [[283, ... 247, ...]
[276, ... 257, ...]
[256, ... 264, ...]
[296, ... 324, ...]
[297, ... nil, ...]
[274, ... nil, ...]
[298, ... nil, ...]
[286, ... nil, ...]
但是在右侧的列上进一步排序会导致 nil 值被重新排序,这会打乱排序。 Nil 值需要保持不变,除非右边的单元格不是 nil,在这种情况下,它应该像往常一样排序。
排序完成后表格应如下所示:
=> [[283, 102, 106, 193, 199, 247, 248, 343],
[276, 108, 111, 204, 207, 257, 259, 367],
[274, 66, 66, 120, 121, nil, 150, nil],
[296, 127, 130, 259, 264, 324, 332, nil],
[256, 105, 111, 212, 216, 264, nil, nil],
[297, 100, 101, 235, 253, nil, nil, nil],
[298, 114, 117, 270, 270, nil, nil, nil],
[286, 116, 116, 213, nil, nil, nil, nil]]
有人可以帮我写一个可以达到这个结果的方法吗?
查看我正在努力实现的真实示例可能会有所帮助。这是电子表格的链接:
https://github.com/SplitTime/OpenSplitTime/blob/master/hardrock2015test.xlsx
每一行都是跑步者的努力。当然,跑步者是按最终完成时间排名的。但是那些没有完成的人会按照他们到达的距离以及到达最后一个航点的时间来排名。
虽然链接的电子表格没有显示它,但排序还需要处理带有右侧时间数据的 nil 值,表示由于任何原因未记录的时间。
【问题讨论】:
-
不清楚你的意思。元素似乎没有改变它们的列。从左到右对每一列进行排序是什么意思?您只能从左到右对(两个或更多)列进行排序。
-
为什么从 274,666,666 开始的行没有进一步向下(因为倒数第二个元素为 nil)?
-
你有什么问题?
-
元素总是留在它们的列中。排序会影响整个行。但是排序标准首先应用于第 2 列,然后应用于第 3 列,依此类推到第 n 列。我将进行编辑以澄清。
-
3 点范围表示法正好适合您使用
- 1的情况。你可以改用(1...sort_array[0].size).each...BTW,为什么你从 1 开始而不是 0?