-2

と呼ぶ操作が必要shake_treeです。基本的なRuby-Fortranのみを使用して再帰アルゴリズムを使用して実装しましたが(「 Fortranコードを任意の言語で記述できます」という古い引用を参照)、はるかに簡潔で慣用的なRuby方法があると思います。

この操作の通称がわからないので、簡単に説明します。次の例のようなハッシュのハッシュがあります。

{
  "-cutoff:" =>
  {
    :flag => {:set_ie1 => [:useCutoff, true]},
    :arg => {:vector_ie1 => :double}
  },
  "-depth:" =>
  {
    :flag => {:set_ie2 => [:useInconsistent, true]},
    :arg => :double,
    :default => 2.0
  },
  "-maxclust:" =>
  {
    :flag => {:set_ie3 => [:useCutoff, false]},
    :arg => {:vector_ie2 => :index}
  },
  :fn => "arrayTypeOptions"
}

のようなユニークなシンボルがあり、ツリーの構造内に埋め込まれています:vector_ie1:set_ie3ルートからシンボルを残すまでのパス以外のツリーのすべてのブランチを削除する必要があります。上記の例を考えると:

shake_tree(specs, :vector_ie1)

戻ります:

{
  "-cutoff:" =>
  {
    :flag => {:set_ie1 => [:useCutoff, true]},
    :arg => {:vector_ie1 => :double}
  }
}

shake_tree(specs, :set_ie2)

戻ります:

{
  "-depth:" =>
  {
    :flag => {:set_ie2 => [:useInconsistent, true]},
    :arg => :double,
    :default => 2.0
  }
}

より経験豊富なRubyコーダーは、このタスクにどのようにアプローチしますか?

4

1 に答える 1

1

これが私の再帰的な実装です。RubyMineshake_treeのスペルチェッカーを快適に保つために (そして の音が好きだったので)呼び出すことにしました。shake_tree specs key

def shake_tree(specs, key)
  parent = find_parent(specs, key)
  parent ? { parent => specs[parent] } : nil
end

def find_parent(specs, key, keypath = [])
  specs.each do |k, v|
    if k == key
      return (keypath + [k])[0]
    elsif v.is_a?(Hash)
      branch = find_parent(v, key, keypath + [k])
      if !branch.nil?
        return branch
      end
    end
  end
  nil
end

これは、上で指定した出力を正確に返します。

これに共通の名前があるかどうか、私はまだ知りたいと思っています。

于 2013-04-26T02:28:20.607 に答える