57474


2つの配列`arr`と`brr`があったとき，`arr`の昇順又は降順のソートに関連して`brr`を並び替えたいです．  
2次元配列でもHashでも構いません（手法が他にあれば教えていただきたいです）  
ご教授よろしくおねがいします．

具体例を以下に示します．`arr`と`brr`の配列の長さは同一の条件です．

[code]

    arr = [5, 8, 1, 3, 4, 7, 9, 6]
    brr = [17, 15, 13, 10, 19, 12, 14, 18]
    
    # 例えば以下
    arr.sort!
    # => [1, 3, 4, 5, 6, 7, 8, 9]
    # => brrは[13, 10, 19, 17, 18, 12, 15, 14]と並び替えられる
    
[/code]


CC BY-SA 4.0
2019-08-19T05:20:16.907
57441
2019-08-21T23:04:50.197
30173
question
ruby
2つの配列を紐づけて，一方の配列の昇順又は降順にソート関連して他方の配列を並び替えたい

[code]

    arr = [5, 8, 1, 3, 4, 7, 9, 6]
    brr = [17, 15, 13, 10, 19, 12, 14, 18]
    
    zipped = arr.zip(brr)
    zipped.sort!
    
    sorted_brr = zipped.map { |pair| pair[1] }
    
    p sorted_brr
    # => [13, 10, 19, 17, 18, 12, 15, 14]
    
[/code]

zip して sort して取り出すと良いと思います。


CC BY-SA 4.0
2019-08-19T05:52:08.260
57447
2019-08-19T05:52:08.260
754
57441
answer


arr と brr のペアの配列を作ってからソートするというのはどうでしょうか。

[code]

    arr = [5, 8, 1, 3, 4, 7, 9, 6]
    brr = [17, 15, 13, 10, 19, 12, 14, 18]
    
    hoge = arr.zip(brr)
    #=> [[5, 17], [8, 15], [1, 13], [3, 10], [4, 19], [7, 12], [9, 14], [6, 18]]
    fuga = hoge.sort_by(&:first)
    #=> [[1, 13], [3, 10], [4, 19], [5, 17], [6, 18], [7, 12], [8, 15], [9, 14]]
    arr = fuga.map(&:first)
    #=> [1, 3, 4, 5, 6, 7, 8, 9]
    brr = fuga.map(&:last)
    #=> [13, 10, 19, 17, 18, 12, 15, 14]
    
[/code]


CC BY-SA 4.0
2019-08-20T04:19:39.603
57474
2019-08-20T04:19:39.603
3249
57441
answer


`sort!`メソッドを読んだときにローカル変数`brr`を書き換えたいのであれば `define_singleton_method`
で`sort!`メソッドを定義しなおして、メソッド定義のブロックの中からローカル変数の中身を書き換えるとよさそうです

[code]

    arr = [5, 8, 1, 3, 4, 7, 9, 6]
    brr = [17, 15, 13, 10, 19, 12, 14, 18]
    
    arr.define_singleton_method(:sort!) do
      map!.with_index { |*x| x }
      super()
      brr = map { |_, index| brr[index] }
      map!(&:first)
    end
    
    # 例えば以下
    arr.sort!
    
    p arr == [1, 3, 4, 5, 6, 7, 8, 9]
    p brr == [13, 10, 19, 17, 18, 12, 15, 14]
    
[/code]


CC BY-SA 4.0
2019-08-20T23:26:14.853
57493
2019-08-20T23:26:14.853
2599
57441
answer


Ruby配列での解答は皆さんすでに書かれています。  
NArrayでやるとこうなります。

[code]

    require 'numo/narray'
    
    a = Numo::Int8[5, 8, 1, 3, 4, 7, 9, 6]
    b = Numo::Int8[17, 15, 13, 10, 19, 12, 14, 18]
    
    b[a.sort_index]
    
[/code]

=> Numo::Int8(view)#shape=[8]  
[13, 10, 19, 17, 18, 12, 15, 14]

Int8が対応できる範囲は狭いので、必要に応じてInt64やDFloatなどをお使いください。


CC BY-SA 4.0
2019-08-21T22:57:54.187
57521
2019-08-21T23:04:50.197
2019-08-21T23:04:50.197
32772
32772
57441
answer