如何在Ruby数组中对整数进行分组以便我可以压缩数组?

时间:2015-01-30 18:37:26

标签: ruby arrays compression

假设我在Ruby 2.1+中有一个整数数组,例如:

[2, 4, 4, 1, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5]

我想做的是压缩数组,以便得到类似的内容:

[2, [4, 2], 1, 6, 7, [5, 8]]

请注意,两个内部数组只包含两个元素。重复的价值和次数。

此外,订单很重要。

**编辑*

对不起,我没有提到单个元素,我不关心计数。所以[2,1]...[1,1],[6,1]...与我无关。

事实上,我真的只对有4个或更多重复整数的组感兴趣,但我不想混淆这个问题。因此,[3,2]可以保留为3,3,但[3,4]将被用来代替3,3,3,3,但这对于问题的主题并不重要。

谢谢!

2 个答案:

答案 0 :(得分:4)

对于Ruby 2.2:

[2, 4, 4, 1, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5]
.slice_when(&:!=)
.map{|a| a.length == 1 ? a.first : [a.first, a.length]}
# => [2, [4, 2], 1, 6, 7, [5, 8]]

对于较旧的Ruby:

[2, 4, 4, 1, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5]
.chunk{|e| e}
.map{|e, a| a.length == 1 ? e : [e, a.length]}
# => [2, [4, 2], 1, 6, 7, [5, 8]]

答案 1 :(得分:0)

没有其他人那么高效,但是很好。

编辑:如下所示,这是如何执行此操作的示例。 Ruby有一个很棒的方法库,内置在Array类中,应该使用它而不是使用索引。

arr = [2, 4, 4, 1, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5]
tempArr = []
newArr = []
for i in 0..(arr.length - 1)
    if arr[i] == arr[i + 1] && arr[i] != arr[i - 1]
        tempArr = [arr[i], 1]
    elsif tempArr[0] == arr[i]
        tempArr[1] += 1
        if arr[i - 1] == arr[i] && arr[i + 1] != tempArr[0]
            newArr.push(tempArr)
        end
    elsif arr[i] != tempArr[0]
        newArr.push(arr[i])
        if tempArr[0] != nil
            tempArr = []
        end
    end
end