0

我想将此文本字符串转换为哈希,以根据用户输入创建页面。

Home
About
- News
-- Local News
-- Global News
- Who We Are
Product

这只是一个示例,但我想将其转换为可以迭代的多维哈希。我想为用户创建一种在 CMS 中创建页面的简单方法。

我已经尝试过拆分字符串和正则表达式,但还没有走多远。

任何帮助将不胜感激!

4

4 回答 4

2

看起来 Yaml 会是你的朋友。查看 Yaml.load。测试.yml:

"Home":
  "About":
    "News":
      "Local News":
      "Global News":
      "Who We Are":
  "Products":

irb

require 'yaml'
YAML.load(File.open('test.yml'))
=> {"home"=>{"About"=>{"News"=>{"Local News"=>nil, "Global News"=>nil, "Who We Are"=>nil}}, "Product"=>nil}}
于 2013-01-11T15:21:41.423 回答
0

@Sergio:这是一条线!(诚​​然,为了“清晰”,我将它分成了几行)

@lt-matt8:如果您真的使用它,那么我对以后阅读您的代码的任何人的理智不承担任何责任 :)

text = <<-TEXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TEXT

hash = text.lines.each_with_object([{}]) {|item, levels|
  item.match(/(-*)\s*(.*)/).captures.tap {|level, title|
    levels[level.size][title] = (levels[level.size + 1] = {})
  }
}.first
# => {"Home"=>{}, "About"=>{"News"=>{"Local News"=>{}, "Global News"=>{}}, "Who We Are"=>{}}, "Product"=>{}}
于 2013-01-11T16:54:39.623 回答
0
txt = <<-TXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TXT

def hashify s
  Hash[s.split(/^(?!-)\s*(.*)/).drop(1).each_slice(2).map{|k, v| [k, hashify(v.to_s.strip.gsub(/^-/, ""))]}]
end

hashify(txt)
# =>
# {
#   "Home"    => {},
#   "About"   => {
#     "News"       => {
#       "Local News"  => {},
#       "Global News" => {}
#     },
#     "Who We Are" => {}
#   },
#   "Product" => {}
# }
于 2013-01-11T16:04:13.553 回答
0

这是我的尝试。我完全承认它看起来并不惯用,并且 ruby​​ stdlib 中可能有一个可以替代它的单行代码。但是,嘿,至少这有效:)

所以,基本思路是这样的:

  • 将文本拆分为单独的行
  • 迭代这个线数组并逐渐构建散列。在执行此操作时继续跟踪“当前节点”
  • 如果这一行的“-”字符多于上一行,则该行必须是上一行的子行
  • 等等

代码:

txt = <<-TXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TXT

def lines_to_hash lines
  res = {}
  last_level = 0
  parent_stack = [res]
  last_line = nil

  lines.each do |line|
    cur_level = line.scan('-').length
    if cur_level > last_level
      parent_stack << parent_stack.last[last_line]
    elsif cur_level < last_level
      parent_stack.pop
    end

    clean_line = line.gsub(/^[-\s]+/, '')
    parent_stack.last[clean_line] = {}
    last_line = clean_line
    last_level = cur_level
  end
  res
end

res = lines_to_hash(txt.split("\n"))
res # => {"Home"=>{}, 
    #     "About"=>{"News"=>{"Local News"=>{}, "Global News"=>{}}, 
    #               "Who We Are"=>{}}, 
    #     "Product"=>{}}

如果有人提出单行,我将奖励 +100 代表赏金:)

于 2013-01-11T15:12:28.633 回答