2016-09-12 15 views
0

私はこのような配列があります。デルタとの配列の配列をソート

[[300, 400], [200, 300], [500, 600], [400, 200]] 

私が欲しい別の配列は、他の値によってソートされ、最初の項目がその値に近づくべきであるようにすることです、私デルタでソートしてみました:

c = [300, 50] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].sort do |a, b| 
    a_width_delta = a.first - c.first 
    a_height_delta = a.last - c.last 
    b_width_delta = b.first - c.first 
    b_height_delta = b.last - c.last 

    (a_width_delta + a_height_delta) <=> (b_width_delta + b_height_delta) 
end 
p "Input #{c}" 
p f 
c = [300, 400] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].sort do |a, b| 
    a_width_delta = a.first - c.first 
    a_height_delta = a.last - c.last 
    b_width_delta = b.first - c.first 
    b_height_delta = b.last - c.last 

    (a_width_delta + a_height_delta) <=> (b_width_delta + b_height_delta) 
end 
p "Input #{c}" 
p f 

この条件は正しいです:

$> ruby fo.rb 
"Input [300, 50]" 
[[200, 300], # other elements] # correct! 

もう一つは間違っている:

"Input [300, 400]" 
[[200, 300], # other elements] # wrong! 

それは次のようになります。

"Input [300, 400]" 
[[300, 400], # other elements] # correct! 

私が必要なのは最初のインデックスに最も近い値を持つ配列です。

+0

私は第二の例のためのあなたの「正しい」結果を生成する一連のルールを思い付くことができません。たとえば、[[500、600]が[200,300]の前に表示されるのはなぜですか? – smarx

+0

あなたがしようとしていることを理解していれば、 '[500,600]'は '200 + 200 = 400'の違いがあります。これは' '[200,300] '100 + 100 = 200'となる。 – smarx

+0

私の悪い、それは少し漠然としています、私はそれが最初のインデックスで最も近い値を持つソートされた配列です。並べ替えの仕方がわからないので、デルタで並べ替えを試みました。 –

答えて

1

"正しい"出力の例が間違っていると思っています。それ以外の場合、私は要件を理解していません。 :-)

私が正しく理解していれば、出発点から各要素の「距離」でソートすることが考えられます。距離は、成分値の差の合計として定義される。例えば。 x1, y1およびx2, y2の場合:|x2-x1| + |y2-y1|

あなたの現在のコードは負の数を不適切に「報酬」しています。

ここには、各計算の絶対値を取るバージョンがあります。あなたの望む出力は得られません。実際に指定した出力が必要な場合は、それを決定するために使用しているルールを記述してください。あなたの質問を編集パー

c = [300, 50] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].sort do |a, b| 
    a_width_delta = (a.first - c.first).abs 
    a_height_delta = (a.last - c.last).abs 
    b_width_delta = (b.first - c.first).abs 
    b_height_delta = (b.last - c.last).abs 

    (a_width_delta + a_height_delta) <=> (b_width_delta + b_height_delta) 
end 
p "Input #{c}" 
p f 

# Output: 
# "Input [300, 50]" 
# [[400, 200], [200, 300], [300, 400], [500, 600]] 


c = [300, 400] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].sort do |a, b| 
    a_width_delta = (a.first - c.first).abs 
    a_height_delta = (a.last - c.last).abs 
    b_width_delta = (b.first - c.first).abs 
    b_height_delta = (b.last - c.last).abs 

    (a_width_delta + a_height_delta) <=> (b_width_delta + b_height_delta) 
end 
p "Input #{c}" 
p f 

# Output: 
# "Input [300, 400]" 
# [[300, 400], [200, 300], [400, 200], [500, 600]] 

EDIT

、あなたが気にすべての出力配列(最小)の最初の要素であると思われます。その場合、分を計算するだけではどうですか?

c = [300, 50] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].min_by { |x| (x.first - c.first).abs + (x.last - c.last).abs } 
p "Input #{c}" 
p f 

# Output: 
# "Input [300, 50]" 
# [400, 200] 


c = [300, 400] 
f = [[200, 300], [300, 400], [400, 200], [500, 600]].min_by { |x| (x.first - c.first).abs + (x.last - c.last).abs } 
p "Input #{c}" 
p f 

# Output: 
# "Input [300, 400]" 
# [300, 400] 
+0

2番目の出力は、最初のインデックスに '[400、200]'を付けた別の結果を出力します。 –

+0

何ですか?あなたは私がやったものとは異なる出力を得ると言っていますか?または、他の何か? – smarx

+0

申し訳ありませんが、コードの型があります。今は同じです。 –

1
▶ λ = lambda do |input, point| 
    [input, point].transpose # to ease the subtraction 
        .map { |e| e.reduce &:- } # distances [x, y] 
        .map(&:abs) # absolute values of distances 
        .reduce(:+) # total distance 
    end 

▶ [[200, 300], [300, 400], [400, 200], [500, 600]].min_by &λ.curry[[300, 50]] 
#⇒ [400, 200] 

▶ [[200, 300], [300, 400], [400, 200], [500, 600]].min_by &λ.curry[[300, 400]] 
#⇒ [300, 400]