消除列表元素的连续重复

时间:2011-04-04 21:43:11

标签: ruby

消除连续重复列表元素的最佳解决方案是什么?

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

5 个答案:

答案 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#eachEnumerator#next。可以使用Kernel#to_enum 1 代替Array#each

1 to_enum是一个Object实例方法,它在Kernel模块中定义,但记录在Object类中。知道了吗?