Как мне преобразовать строку Ruby со скобками в массив?

StackOverflow https://stackoverflow.com/questions/38409

  •  09-06-2019
  •  | 
  •  

Вопрос

Я хотел бы преобразовать следующую строку в массив / вложенный массив:

str = "[[this, is],[a, nested],[array]]"

newarray = # this is what I need help with!

newarray.inspect  # => [['this','is'],['a','nested'],['array']]
Это было полезно?

Решение

С YAML вы получите то, что хотите.

Но есть небольшая проблема с вашей строкой.YAML ожидает, что за запятой будет пробел.Итак, нам нужно это

str = "[[this, is], [a, nested], [array]]"

Код:

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"]]

Другие советы

Для смеха.

 ary = eval("[[this, is],[a, nested],[array]]".gsub(/(\w+?)/, "'\\1'") )
 => [["this", "is"], ["a", "nested"], ["array"]]

Отказ от ответственности: вам определенно не следует делать это, поскольку eval - ужасная идея, но она быстра и имеет полезный побочный эффект - генерирует исключение, если ваши вложенные массивы недопустимы

Вы также можете рассматривать это как почти JSON. Если строки на самом деле являются только буквами, как в вашем примере, то это будет работать:

JSON.parse(yourarray.gsub(/([a-z]+)/,'"\1"'))

Если бы они могли иметь произвольные символы (кроме [],), вам нужно немного больше:

JSON.parse("[[this, is],[a, nested],[array]]".gsub(/, /,",").gsub(/([^\[\]\,]+)/,'"\1"'))

Похоже, основная задача разбора. Обычно подход, который вы хотите использовать, заключается в создании рекурсивной функции с использованием следующего общего алгоритма

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

Единственная хитрая часть здесь - это разделение ввода на один ','. Для этого можно написать отдельную функцию, которая будет сканировать строку и вести подсчет открытых скобок - закрытых корзин, замеченных до сих пор. Затем разделяйте запятыми только тогда, когда число равно нулю.

Создайте рекурсивную функцию, которая принимает строку и целочисленное смещение, и " читает " из массива. То есть, он должен вернуть массив или строку (которую он прочитал) и целочисленное смещение, указывающее после массива. Например:

s = "[[this, is],[a, nested],[array]]"

yourFunc(s, 1) # returns ['this', 'is'] and 11.
yourFunc(s, 2) # returns 'this' and 6.

Затем вы можете вызвать его с помощью другой функции, которая обеспечивает смещение 0 и гарантирует, что конечным смещением является длина строки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top