0

我在 Ruby 中有以下数据结构(键是字符串,值是数组的哈希)。

X = { "id": [2, 4, 1],  "name": ["a", "b", "c"], "time": [1, 0, 2]}

我想对与字段“时间”关联的数组进行排序,但我希望所有其他数组以一致的方式排序。示例:排序后,X 应如下所示。

X = {"id": [4, 2, 1], "name": ["b", "a", "c"], "time": [0, 1, 2]}

我以一种非常丑陋的方式解决了这个问题(因为我不知道该怎么做)。我所做的是创建一个时间副本,然后是 zip id 和 time,然后对其进行排序,然后是 zip name 和 time_copy 并对其进行排序。然后解压。我很确定这是一种糟糕的方法。其他人可以教我更好的方法吗?

4

3 回答 3

2

如果三段数据应该属于一起,我认为您应该认真考虑将数据结构从数组哈希更改为哈希数组。否则,您可能会遇到各种麻烦(例如,如果您不小心使数组长度不等,会发生什么情况)——事实上,正如您所发现的,它使排序变得相当困难。

如果您坚持使用哈希作为输入格式,您可以按如下方式进行转换

hash = {id: [2, 4, 1],  name: ["a", "b", "c"], time: [1, 0, 2]}
array = hash.map{|k,v| [k].product(v)}.transpose.map{|h| Hash[h]}
# => [{id: 2, name: "a", time: 1}, ...]

在哈希格式数组中,您可以非常轻松地对字段进行排序

array.sort_by{|h| h[:time]}
于 2013-01-21T23:27:52.940 回答
1

使用@tokland 对另一个问题的回答并应用于values_at结果:

h = { id: [2, 4, 1],  name: ["a", "b", "c"], time: [1, 0, 2]}

time_indices = h[:time].each_with_index.sort_by(&:first).map(&:last)
h.values.each{|ar| ar.replace(ar.values_at(*time_indices))}
#=> {:id=>[4, 2, 1], :name=>["b", "a", "c"], :time=>[0, 1, 2]}
于 2013-01-21T23:49:38.700 回答
0

和steenslag的差不多,但我觉得map.with_index应该用。

permutation = X["time"].map.with_index{|*xi| xi}.sort_by(&:first).map(&:last)
X.values.each{|a| a.replace(a.values_at(*permutation))}
于 2013-01-22T00:22:02.077 回答