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

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

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

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

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

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

鉴于一系列方向:

 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相对容易。

 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 
 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"] 

这是一种应该直截了当的方法。 与我删除的几乎答案一样,它正在考虑数字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 #=> [] 

我们可以使用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