我有一个这样的数组:
[[300, 400], [200, 300], [500, 600], [400, 200]]
我想创建另一个数组按其他值排序第一项应该更接近那个值,我尝试按delta排序:
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!
我所需要的是一个数组的最接近的值在第一个索引
我希望你的"正确"输出的例子是错误的。否则我就不明白要求了。: -)
如果我理解正确的话,这个想法是根据每个元素到起始点的"距离"进行排序。距离定义为各分量值之差之和。例如,对于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]]
编辑
根据对您的问题的编辑,似乎您所关心的只是输出数组中的第一个元素(最小值)。这样的话,为什么不直接计算最小值呢?
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]
▶ λ = 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]