消除连续重复列表元素的最佳解决方案是什么?
list = compress(['a','a','a','a','b','c','c','a','a','d','e','e','e','e']).
p list # => # ['a','b','c','a','d','e']
我有这个:
def compress(list)
list.map.with_index do |element, index|
element unless element.equal? list[index+1]
end.compact
end
Ruby 1.9.2
答案 0 :(得分:23)
使用Enumerable#chunk
的好机会,只要您的列表不包含nil
:
list.chunk(&:itself).map(&:first)
对于2.2.x以上的Ruby,您可以require "backports/2.2.0/kernel/itself"
或使用{|x| x}
代替(&:itself)
。
对于早于1.9.2的Ruby,您可以require "backports/1.9.2/enumerable/chunk"
获得纯Ruby版本。
答案 1 :(得分:6)
这样做(假设每个元素都是单个字符)
list.join.squeeze.split('')
答案 2 :(得分:3)
Ruby 1.9 +
list.select.with_index{|e,i| e != list[i+1]}
关于@sawa,谁告诉我关于with_index
:)
正如@ Marc-AndréLafortune注意到,如果列表末尾有nil
,它将不适合您。我们可以用这个丑陋的结构修复它
list.select.with_index{|e,i| i < (list.size-1) and e != list[i+1]}
答案 3 :(得分:1)
# Requires Ruby 1.8.7+ due to Object#tap
def compress(items)
last = nil
[].tap do |result|
items.each{ |o| result << o unless last==o; last=o }
end
end
list = compress(%w[ a a a a b c c a a d e e e e ])
p list
#=> ["a", "b", "c", "a", "d", "e"]
答案 4 :(得分:0)
arr = ['a','a','a','a','b','c','c','a','a','d','e','e','e','e']
enum = arr.each
#=> #<Enumerator: ["a", "a", "a", "a", "b", "c", "c", "a", "a", "d",
# "e", "e", "e", "e"]:each>
a = []
loop do
n = enum.next
a << n unless n == enum.peek
end
a #=> ["a", "b", "c", "a", "d"]
Enumerator#peek在已经返回枚举器的最后一个元素时引发StopIteration
异常。 Kernel#loop通过突破循环来处理该异常。
请参阅Array#each和Enumerator#next。可以使用Kernel#to_enum 1 代替Array#each
。
1 to_enum
是一个Object
实例方法,它在Kernel
模块中定义,但记录在Object
类中。知道了吗?