我正在寻找一种方法来检测数组中的以下值是否重复,如果是,则删除它。它应该适用于字符串和整数。
例如,给定数组:
arr = ["A", "B", "B", "C", "c", "A", "D", "D"]
返回:
arr = ["A", "B", "C", "c", "A", "D"]
我尝试创建一个空数组a
,然后铲除值,提供以下值不等于当前值。我试着这样做:
arr.each do |x|
following_value = arr.index(x) + 1
a << x unless x == arr[following_value]
end
不幸的是,它没有将重复值中的一个铲入数组中,而是没有铲除。
arr = ["A", "C", "c", "A"]
有人可以帮忙吗?奖励积分告诉我我的方法究竟出了什么问题。
谢谢!
答案 0 :(得分:3)
首先,这里是更简单的解决方案:
> arr.delete_if.with_index { |e, ind| e == arr[ind+1] }
#=> ["A", "B", "C", "c", "A", "D"]
但是,这个解决方案会改变arr
。
以下是没有变异的单行解决方案:
arr.each_with_index.with_object([]) { |(e, ind), res| res << e if e != arr[ind+1] }
arr.each_with_object([]) { |e, res| res << e if res.last != e }
您的问题在这一行:a << x unless x == arr[following_value]
您说:如果element
不等于result
,请将next element
放入arr.each do |x|
a << x unless a.last == x
end
。所以,相反,您可以这样说:如果结果的最后一个元素不等于,则将此元素置于结果中:
&varlist. = OriginCd,DestinCd
答案 1 :(得分:2)
我会使用select,所以你可以这样做:
a = ["A", "B", "B", "C", "c", "A", "D", "D"]
# without mutation
b = a.select.with_index { |e, i| a[i+1] != e }
a #=> ["A", "B", "B", "C", "c", "A", "D", "D"]
b #=> ["A", "B", "C", "c", "A", "D"]
# with mutation
a.select!.with_index { |e, i| a[i+1] != e }
a #=> ["A", "B", "C", "c", "A", "D"]
BTW您的方法无效,因为arr.index(x)
returns index of first object for which block is true:
arr = ["A", "B", "B", "C", "c", "A", "D", "D"]
arr.each do |x|
puts "#{x} has index #{arr.index(x)}"
end
A has index 0
B has index 1
B has index 1 # you were expecting 2
C has index 3
c has index 4
A has index 0 # you were expecting 5
D has index 6
D has index 6 # you were expecting 7
答案 2 :(得分:1)
这是一个简洁的选择:
arr = ["A", "B", "B", "C", "c", "A", "D", "D"]
arr.chunk(&:itself).map(&:first)
# => ["A", "B", "C", "c", "A", "D"]
在repl.it上查看:https://repl.it/JGV4/1
答案 3 :(得分:1)
来自this的Cary Swoveland回答:
def remove_consecs ar
enum = ar.each
loop.with_object([]) do |_, arr|
curr = enum.next
nxt = arr.last || enum.peek
arr << curr if curr != nxt
end
end
remove_consecs ["A", "B", "B", 'D', "C", "c", "A", "D", "D"]
#=> ["A", "B", "D", "C", "c", "A", "D"]