0

私は以下のデータ構造を持っており、最上位のキー (lo、eth0、または eth1) を返そうとしていますが、その値のどこかに再帰的かつ任意の深さがある場合は、指定された文字列です。文字列の最初のインスタンスが見つかったら、検索を終了します。

任意の数のネストされたハッシュと配列を含むハッシュの奥深くにあるキーと値のペアを 見つける

h.find{ |k,v| break k if v.include? "number" }
 => "eth0"

h.find{ |k,v| break k if v.include? "10.0.128.26" }
 => nil
#Should return eth0

このようなネストされたデータ構造を一般的に操作する方法を知りたいのですが、特定のサブハッシュ、私の場合はアドレス内で具体的に検索できることに落ち着きます。

    h = \
    {"lo"=>
      {"mtu"=>"65536",
       "flags"=>["LOOPBACK", "UP", "LOWER_UP"],
       "encapsulation"=>"Loopback",
       "addresses"=>
        {"127.0.0.1"=>
          {"family"=>"inet",
           "prefixlen"=>"8",
           "netmask"=>"255.0.0.0",
           "scope"=>"Node"}},
       "state"=>"unknown"},
     "eth0"=>
      {"type"=>"eth",
       "number"=>"0",
       "mtu"=>"1500",
       "flags"=>["BROADCAST", "MULTICAST", "UP", "LOWER_UP"],
       "encapsulation"=>"Ethernet",
       "addresses"=>
        {"00:0C:29:1A:64:6A"=>{"family"=>"lladdr"},
         "10.0.128.26"=>
          {"family"=>"inet",
           "prefixlen"=>"24",
           "netmask"=>"255.255.255.0",
           "broadcast"=>"10.0.128.255",
           "scope"=>"Global"}},
       "state"=>"up",
       "arp"=>
        {"10.0.128.31"=>"00:0c:29:04:12:9a",
         "10.0.128.100"=>"00:0c:29:5b:b4:46",
         "10.0.128.30"=>"00:0c:29:05:a4:c7",
         "10.0.128.18"=>"00:0c:29:6a:3f:75",
         "10.0.128.3"=>"0c:c4:7a:c0:31:d1",
         "10.0.128.43"=>"00:0c:29:01:eb:6b",
         "10.0.128.44"=>"00:09:0f:09:00:03",
         "10.0.128.14"=>"00:0c:29:d2:15:80",
         "10.0.128.22"=>"00:0c:29:18:99:30"},
       "routes"=>
        [{"destination"=>"10.0.128.0/24",
          "family"=>"inet",
          "scope"=>"link",
          "proto"=>"kernel",
          "src"=>"10.0.128.26"}],
       "link_speed"=>10000,
       "duplex"=>"Full",
       "port"=>"Twisted Pair",
       "transceiver"=>"internal",
       "auto_negotiation"=>"off",
       "mdi_x"=>"Unknown",
       "ring_params"=>
        {"max_rx"=>4096,
         "max_rx_mini"=>0,
         "max_rx_jumbo"=>2048,
         "max_tx"=>4096,
         "current_rx"=>256,
         "current_rx_mini"=>0,
         "current_rx_jumbo"=>128,
         "current_tx"=>512}},
     "eth1"=>
      {"type"=>"eth",
       "number"=>"1",
       "mtu"=>"1500",
       "flags"=>["BROADCAST", "MULTICAST", "UP", "LOWER_UP"],
       "encapsulation"=>"Ethernet",
       "addresses"=>
        {"00:0C:29:1A:64:74"=>{"family"=>"lladdr"},
         "11.11.11.1"=>
          {"family"=>"inet",
           "prefixlen"=>"24",
           "netmask"=>"255.255.255.0",
           "broadcast"=>"11.11.11.1",
           "scope"=>"Global"}},
       "state"=>"up",
       "routes"=>
        [{"destination"=>"default", "family"=>"inet", "via"=>"11.11.11.1"},
         {"destination"=>"11.11.11.1/24",
          "family"=>"inet",
          "scope"=>"link",
          "proto"=>"kernel",
          "src"=>"11.11.11.1"}],
       "link_speed"=>10000,
       "duplex"=>"Full",
       "port"=>"Twisted Pair",
       "transceiver"=>"internal",
       "auto_negotiation"=>"off",
       "mdi_x"=>"Unknown",
       "ring_params"=>
        {"max_rx"=>4096,
         "max_rx_mini"=>0,
         "max_rx_jumbo"=>2048,
         "max_tx"=>4096,
         "current_rx"=>256,
         "current_rx_mini"=>0,
         "current_rx_jumbo"=>128,
         "current_tx"=>512}}}
4

2 に答える 2

3

トップレベルのキーに興味があるので、次のようにすることができます:

hash.find{ |k,v| break k if v.to_s.include? "10.0.128.26" }
#=> eth0

を使用v.to_sすることで、ハッシュの文字列表現で検索でき、再帰を回避することもできます。

于 2017-05-04T03:31:08.533 に答える