0

Rubyには次のデータ構造があります(キーが文字列で値が配列のハッシュ)。

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

フィールド「time」に関連付けられた配列を並べ替えたいのですが、他のすべての配列を一貫した方法で並べ替えたいと思います。例:並べ替え後、Xは次のようになります。

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

私はこれを本当に醜い方法で解決しました(方法がわからないため)。私がしたことは、時間のコピーを作成し、次にidとtimeを圧縮して並べ替え、次にnameとtime_copyをzipして並べ替えることでした。次に解凍します。私はこれがそれをするためのひどい方法であるとかなり確信しています。他の誰かが私にもっと良い方法を教えてもらえますか?

4

3 に答える 3

2

3つのデータが一緒に属することになっている場合は、データ構造を配列のハッシュからハッシュの配列に変更することを真剣に検討する必要があると思います。そうしないと、あらゆる種類の問題が発生する可能性があります(たとえば、誤って配列の長さを等しくしなかった場合はどうなりますか)。実際、ご存知のとおり、並べ替えがかなり難しくなります。

入力形式としてハッシュを使用している場合は、次のように変換できます

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

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 に答える