如何从数组中删除相反的值?

时间:2016-09-28 12:24:32

标签: arrays ruby

我有一个问题,我正在尝试创建一个方向数组,其中每个方向都不是多余的。

plan = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]

正如您所看到的,此计划中的大多数值都是多余的,您也可以简单地告诉此人"WEST"

plan = ["NORTH", "WEST", "SOUTH", "EAST"]

我还希望上面的计划返回一个空数组。

5 个答案:

答案 0 :(得分:6)

给出一系列指示:

plan = %w[NORTH SOUTH SOUTH EAST WEST NORTH WEST]
#=> ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]

我会将路线转换为xy坐标:

x, y = 0, 0

plan.each do |direction|
  case direction
  when 'NORTH' then y += 1
  when 'EAST'  then x += 1
  when 'SOUTH' then y -= 1
  when 'WEST'  then x -= 1
  end
end

'NORTH'增加y'SOUTH'减少y'EAST' / 'WEST'x相同。

使用示例数组,它给出了:

x #=> -1
y #=> 0

这些必须转换回一系列方向:

[
  *Array.new(y.abs) { y.positive? ? 'NORTH' : 'SOUTH' },
  *Array.new(x.abs) { x.positive? ? 'EAST' : 'WEST' }
]
#=> ["WEST"]

虽然这不是最短的代码,但掌握IMO相对容易。

答案 1 :(得分:4)

OPPOSITES = {
  'NORTH' => 'SOUTH',
  'WEST'  => 'EAST',
  'EAST'  => 'WEST',
  'SOUTH' => 'NORTH',
}

frequencies = plan.group_by(&:itself).map do |direction, occurrences|
  [direction, occurrences.size]
end.to_h

OPPOSITES.flat_map do |direction, opposite_direction|
  uncounteracted_occurances =
    frequencies[direction] - frequencies[opposite_direction]

  [direction] * [uncounteracted_occurances, 0].max
end

答案 2 :(得分:2)

def simplify(plan)
  h = { "SOUTH"=>"NORTH", "NORTH"=>"SOUTH", "EAST"=>"WEST", "WEST"=>"EAST" }
  plan.each_with_object([]) { |direction, arr|
    (idx = arr.index(h[direction])) ? arr.delete_at(idx) : arr << direction }
end

simplify ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
  #=> ["WEST"] 
simplify ["NORTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST", "WEST"]
  #=> ["NORTH", "WEST", "WEST"] 
simplify ["NORTH", "EAST", "WEST", "NORTH", "WEST"]
  #=> ["NORTH", "NORTH", "WEST"] 

答案 3 :(得分:0)

这是一种应该直截了当的方法。与我删除的几乎答案一样,它考虑了数字2D平面上的方向,但没有不必要的复杂性(双关语)。因此,这在概念上类似于@Stefan已经发布的优秀答案。

def kanye plan
  r = plan.count("EAST")  - plan.count("WEST")
  i = plan.count("NORTH") - plan.count("SOUTH")

  res = []
  r.positive? ? r.times { res << "EAST" }  : (-r).times { res << "WEST" }
  i.positive? ? i.times { res << "NORTH" } : (-i).times { res << "SOUTH" }
  res
end

示例:

plan = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
kanye plan #=> ["WEST"]

plan = ["NORTH", "WEST", "SOUTH", "EAST"]
kanye plan #=> []

plan = ["NORTH"]
kanye plan #=> ["NORTH"]

plan = []
kanye plan #=> []

答案 4 :(得分:0)

我们可以使用Argand-Gauss平面来表示地理坐标,其中我们将告诉南北运动的实部,而想象部分则指向东西方向。 通过这种方式,运行一个简单的复数和就足够了。

plan=["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
dict = {"NORTH"=>1, "SOUTH"=>-1, "EAST"=>(0+1i), "WEST"=>(0-1i)}

# We substitute for each direction a complex number
dict.each{|coord,number| plan.map!{|item| item==coord ? number : item}}
# We run a simple sum
direction = plan.reduce(&:+)  # (0-1i)
puts dict.key(direction)   #=> WEST

re=direction.real
im=direction.imag

if re!=0 and im!=0
  puts "Direction: #{re.abs} #{dict.key(re/re.abs)} #{im.abs} #{dict.key((im/im.abs) *(1i))}"
elsif re!=0 and im==0
  puts "Direction: #{re.abs} #{dict.key(re/re.abs)}"
elsif re==0 and im!=0
   puts "Direction: #{im.abs} #{dict.key((im/im.abs) *(1i))}"
else
  puts "I did not move"
end

#=> Direction: 1 WEST