2012-03-16 23 views
3

举例来说,如果我有一个这样的数组:如何在Ruby中用分隔符分割数组?

[:open, 1, :open, 2, 3, :close, 4, :close, :open, 5, :close] 

我想这一点:

[[1, [2, 3], 4], [5]] 

:open有效地成为[:close成为]

+0

你试过到目前为止什么码? – GetSet 2012-03-16 13:47:04

回答

10

你可以可能是用堆栈做到这一点,但递归设计很容易:

#!/usr/bin/env ruby 

x = [:open, 1, :open, 2, 3, :close, 4, :close, :open, 5, :close] 

def parse(list) 
    result = [] 
    while list.any? 
    case (item = list.shift) 
    when :open 
     result.push(parse(list)) 
    when :close 
     return result 
    else 
     result.push(item) 
    end 
    end 

    return result 
end 

puts parse(x).inspect 

请注意,这将破坏您的原始数组。如果你想保存它,你应该在clone之前通过它。

+5

不错的解决方案,) – 2012-03-16 14:00:36

+1

不错,优雅的解决方案! – suvankar 2012-03-16 14:28:25

+2

我不知道你可以使用'any?'作为'empty?'的否定。这很酷。 – sawa 2012-03-16 15:09:35

4
ar = [:open, 1, :open, 2, 3, :close, 4, :close, :open, 5, :close] 
p eval(ar.inspect.gsub!(':open,', '[').gsub!(', :close', ']')) 
#=> [[1, [2, 3], 4], [5]] 
+0

大声笑,我只是想发布这个黑客解决方案:) – fl00r 2012-03-16 14:10:32

+0

我可以建议使用'/,\ s +:close /'。在ruby 1.9中,你可以使用'to_s'而不是'inspect' – fl00r 2012-03-16 14:12:31

+0

这是一个很少的泛型,因为它只适用于文字数组。另外,你不需要在':close':'.gsub!(':close',']')'之前替换'''就足够了。 – 2012-03-16 14:16:14

0

同样以steenslag,但干净了一点

a = [:open, 1, :open, 2, 3, :close, 4, :close, :open, 5, :close] 
eval(a.to_s.gsub(':open,','[').gsub(', :close',']')) 
#=> [[1, [2, 3], 4], [5]]