【问题标题】:Reordering an array in the same order as another array was reordered以与重新排序另一个数组相同的顺序重新排序数组
【发布时间】:2012-02-14 15:15:41
【问题描述】:

我有两个长度相同的数组a、b:

a = [a_1, a_2, ..., a_n]
b = [b_1, b_2, ..., b_n]

当我使用sort_by!对a进行排序时,a的元素会以不同的顺序排列:

a.sort_by!{|a_i| some_condition(a_i)}

如何以与重新排序 a 相同的顺序/重新排列来重新排序 b?例如,如果a 在sort_by! 之后是

[a_3, a_6, a_1, ..., a_i_n]

那我想要

[b_3, b_6, b_1, ..., b_i_n]

编辑

我需要在原地完成它(即,保留a、b 的 object_id)。鉴于排序数组,到目前为止给出的两个答案很有用:

a_sorted
b_sorted

我可以的

a.replace(a_sorted)
b.replace(b_sorted)

但如果可能的话,我想直接做。如果没有,我会接受已经给出的答案之一。

【问题讨论】:

  • 如何定义 b 的“相同顺序”?旧索引 -> 新索引对于 b 的每个元素都等效?
  • @MarkThomas 我将其定义为具有相同的置换矩阵 (en.wikipedia.org/wiki/Permutation_matrix)。
  • 您是否需要保存置换矩阵(或向量,因为它可能在这种情况下)?
  • @MarkThomas 我不需要置换矩阵。
  • 现在您已经编辑了您的问题,我认为保存它可能会很有用。然后,您可以将其“应用”到 a 和 b 以保留对象 ID。既然你已经接受了一个答案,如果它对你很重要,你可以再问一个问题。

标签: ruby arrays algorithm sorting ruby-1.9.3


【解决方案1】:

一种方法是将两个数组压缩在一起并同时对它们进行排序。大概是这样的吧?

a = [1, 2, 3, 4, 5]
b = %w(a b c d e)

a,b = a.zip(b).sort_by { rand }.transpose

p a #=> [3, 5, 2, 4, 1]
p b #=> ["c", "e", "b", "d", "a"]

【讨论】:

  • 你的想法看起来不错,但有没有办法做到这一点?请查看对我的问题的修改。
【解决方案2】:

怎么样:

ary_a = [ 3, 1, 2] # => [3, 1, 2]
ary_b = [ 'a', 'b', 'c'] # => ["a", "b", "c"]
ary_a.zip(ary_b).sort{ |a,b| a.first <=> b.first }.map{ |a,b| b } # => ["b", "c", "a"]

或

ary_a.zip(ary_b).sort_by(&:first).map{ |a,b| b } # => ["b", "c", "a"]

【讨论】:

  • 你的想法看起来不错,但有没有办法做到这一点?请查看我的问题的编辑。
【解决方案3】:

如果条目是唯一的,则以下可能有效。我没有测试过。这是部分复制自https://stackoverflow.com/a/4283318/38765

temporary_copy = a.sort_by{|a_i| some_condition(a_i)}
new_indexes = a.map {|a_i| temporary_copy.index(a_i)}

a.each_with_index.sort_by! do |element, i|
  new_indexes[i]
end

b.each_with_index.sort_by! do |element, i|
  new_indexes[i]
end

【讨论】:

  • 我一直在想这样的事情,但我认为 Enumerator 类没有 map 和 sort_by 等方法的就地修改版本。
  • 谢谢。这样做是我想要的。我需要看看在使用 chron/the Tin Man 的解决方案与 replace 或您的答案之间哪个更快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2011-01-27
相关资源
最近更新 更多