用delta对数组的数组进行排序



我有一个这样的数组:

[[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, y1x2, 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]

相关内容

  • 没有找到相关文章

最新更新