Como faço para converter um Rubi de seqüência de caracteres com suportes para uma matriz?
Pergunta
Eu gostaria de converter-se a seguinte seqüência de caracteres em uma matriz/matriz aninhada.:
str = "[[this, is],[a, nested],[array]]"
newarray = # this is what I need help with!
newarray.inspect # => [['this','is'],['a','nested'],['array']]
Solução
Você vai conseguir o que você quer com YAML.
Mas há um pequeno problema com sua cadeia de caracteres.YAML espera-se que há um espaço depois da vírgula.Então nós precisamos desse
str = "[[this, is], [a, nested], [array]]"
Código:
require 'yaml'
str = "[[this, is],[a, nested],[array]]"
### transform your string in a valid YAML-String
str.gsub!(/(\,)(\S)/, "\\1 \\2")
YAML::load(str)
# => [["this", "is"], ["a", "nested"], ["array"]]
Outras dicas
Para rir:
ary = eval("[[this, is],[a, nested],[array]]".gsub(/(\w+?)/, "'\\1'") )
=> [["this", "is"], ["a", "nested"], ["array"]]
Isenção de responsabilidade:Você definitivamente não deve fazer isso como eval
é uma idéia terrível, mas ele é rápido e tem o efeito secundário útil de lançar uma exceção se o seu matrizes aninhadas não são válidos
Você também pode tratá-lo como quase-JSON.Se as cadeias de caracteres são realmente apenas letras, como no seu exemplo, então isso vai funcionar:
JSON.parse(yourarray.gsub(/([a-z]+)/,'"\1"'))
Se eles pudessem ter arbitrário de caracteres (diferente de [ ] , ), você precisaria de um pouco mais:
JSON.parse("[[this, is],[a, nested],[array]]".gsub(/, /,",").gsub(/([^\[\]\,]+)/,'"\1"'))
Parece um básicas de análise de tarefas.Geralmente, a abordagem que você vai querer fazer é criar uma função recursiva com o seguinte algoritmo geral
base case (input doesn't begin with '[') return the input
recursive case:
split the input on ',' (you will need to find commas only at this level)
for each sub string call this method again with the sub string
return array containing the results from this recursive method
A única slighlty parte do truque aqui é dividir a entrada em um único ','.Você pode escrever uma função separada para este que faria a varredura através da cadeia e manter uma contagem do openbrackets - closedbrakets visto até então.Então só dividir em vírgulas quando a contagem é igual a zero.
Faça uma função recursiva que leva a seqüência de caracteres e um número inteiro de deslocamento, e "lê" uma matriz.Que é, tem que retornar um array ou uma string (que ele tenha lido) e um inteiro deslocamento apontando depois que a matriz.Por exemplo:
s = "[[this, is],[a, nested],[array]]"
yourFunc(s, 1) # returns ['this', 'is'] and 11.
yourFunc(s, 2) # returns 'this' and 6.
Em seguida, você pode chamá-lo com outra função que fornece um deslocamento de 0, e certifica-se de que o acabamento deslocamento é o comprimento da cadeia.