【问题标题】:Ruby JSON node select, view & value change [duplicate]Ruby JSON节点选择,视图和值更改[重复]
【发布时间】:2015-08-19 11:49:20
【问题描述】:

我正在尝试从 JSON 解析文件中选择一个节点,并通过使用点分隔节点来显示节点/键层次结构。

json_hash =
{
    "Samples": {
        "Locations": {
            "Presets": "c:\\Presets\\Inst",
            "Samples": "c:\\Samples\\seperates\\round_robin"
        },
        "Format": {
            "Type": "AIFF",
            "Samplerate": 48,
            "Bitrate": 24
        },
        "Groupings": {
            "Type": "dynamic",
            "Sets": {
                "Keyswitch": "enabled",
                "Mods": "Enabled"
            }
        },
        "Ranges": {
            "Keys": {
                "LowKey": 30,
                "HighKey": 80,
                "LowVel": 0,
                "MidVel": 53,
                "HighVel": 127
            }
        },
        "Dynamics": {
            "DN": {
                "MultiRange": "enabled",
                "Range": [
                    "0-36",
                    "37-80"
                ]
            }
        }
    },
    "Modulation": {
        "Pitch": true,
        "Range": []
    },
    "Encoded": false,
    "test": "test_one"
}

我的想法是输出这样的东西;

Samples.Locations.Presets => c:\Presets\Inst
Samples.Locations.Samples => c:\Samples\seperates\round_robin

我设法得到了这个;

Presets. => c:\Presets\Inst 
Presets.Samples. => c:\Samples\seperates\round_robin

使用此代码:

def node_tree(hash)
  kl = ''
  hash.each do |k, v|
    kl << "#{k}."
    if v.kind_of?(Hash)
      node_tree(v)
    else
      print "#{kl} => "
      print "#{Array(v).join(', ')}\n"
    end
  end
end

node_tree(json_hash)

如果我可以显示完整的节点层次结构,然后能够使用点分隔节点选择一个节点并更改值,那就太好了。

所以我可以将 Samples.Dynamics.DN.Range0-36, 37-80 更改为 0-30, 31-60, 61-90

key = 'Samples.Dynamics.DN.Range'
value = %w(0-30 31-60 61-90)

node_set('Samples.Dynamics.DN.Range', value)

在我弄清楚如何最好地显示和选择节点和值之前,我无法处理后者。

【问题讨论】:

  • 我不太明白PresetsSamples 路径与Samples.Dynamics.DN.Range 的关系。

标签: ruby json


【解决方案1】:

使用this 方法可以展平哈希:

    def flat_hash(hash, k = [])
      return { k => hash } unless hash.is_a?(Hash)
      hash.inject({}) { |h, v| h.merge! flat_hash(v[-1], k + [v[0]]) }
    end

p flat_hash(json_hash)

#=> {["Samples", "Locations", "Presets"]=>"c:\\Presets\\Inst", ["Samples", "Locations", "Samples"]=>"c:\\Samples\\seperates\\round_robin", ["Samples", "Format", "Type"]=>"AIFF", ["Samples", "Format", "Samplerate"]=>48, ["Samples", "Format", "Bitrate"]=>24, ["Samples", "Groupings", "Type"]=>"dynamic", ["Samples", "Groupings", "Sets", "Keyswitch"]=>"enabled", ["Samples", "Groupings", "Sets", "Mods"]=>"Enabled", ["Samples", "Ranges", "Keys", "LowKey"]=>30, ["Samples", "Ranges", "Keys", "HighKey"]=>80, ["Samples", "Ranges", "Keys", "LowVel"]=>0, ["Samples", "Ranges", "Keys", "MidVel"]=>53, ["Samples", "Ranges", "Keys", "HighVel"]=>127, ["Samples", "Dynamics", "DN", "MultiRange"]=>"enabled", ["Samples", "Dynamics", "DN", "Range"]=>["0-36", "37-80"], ["Modulation", "Pitch"]=>true, ["Modulation", "Range"]=>[], ["Encoded"]=>false, ["test"]=>"test_one"}

对有效路径使用正则表达式/([A-Z|a-z]:\\[^*|"&lt;&gt;?\n]*)|(\\\\.*?\\.*)/可以过滤扁平化哈希:

VALID_PATH_REGEXP = /([A-Z|a-z]:\\[^*|"<>?\n]*)|(\\\\.*?\\.*)/

flat_hash(json_hash).each_pair do |k, v|
  puts "#{Array(k).join('.')} => #{v}" if v.to_s =~ VALID_PATH_REGEXP
end

#=> Samples.Locations.Presets => c:\Presets\Inst
#=> Samples.Locations.Samples => c:\Samples\seperates\round_robin

最终代码:

require 'json'

VALID_PATH_REGEXP = /([A-Z|a-z]:\\[^*|"<>?\n]*)|(\\\\.*?\\.*)/

json_hash = JSON.parse(File.read('example.json'))

def flat_hash(hash, k = [])
  return { k => hash } unless hash.is_a?(Hash)
  hash.inject({}) { |h, v| h.merge! flat_hash(v[-1], k + [v[0]]) }
end

flat_hash(json_hash).each_pair do |k, v|
  puts "#{Array(k).join('.')} => #{v}" if v.to_s =~ VALID_PATH_REGEXP
end

#=> Samples.Locations.Presets => c:\Presets\Inst
#=> Samples.Locations.Samples => c:\Samples\seperates\round_robin

更新:

这可能会更好地返回带有结果的哈希,而不是仅仅打印它们:

require 'json'

VALID_PATH_REGEXP = /([A-Z|a-z]:\\[^*|"<>?\n]*)|(\\\\.*?\\.*)/

json_hash = JSON.parse(File.read('example.json'))

def flat_hash(hash, k = [])
  return { k => hash } unless hash.is_a?(Hash)
  hash.inject({}) { |h, v| h.merge! flat_hash(v[-1], k + [v[0]]) }
end

def node_tree(hash)
  flat_hash(hash).map { |k, v| [Array(k).join('.'), v] if v.to_s =~ VALID_PATH_REGEXP }.compact.to_h
end

p node_tree(json_hash)

#=> {"Samples.Locations.Presets"=>"c:\\Presets\\Inst", "Samples.Locations.Samples"=>"c:\\Samples\\seperates\\round_robin"}

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 2018-02-06
    • 2014-08-12
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多