0

Skill多くの前提条件 (またはモデル内) を持つモデルがありprereqs、スキルの前提条件の N レベルの深さのマップを作成する必要があります。この情報を Javascript に渡す必要があるためです (私のcontroller) を使用して、このスキルと他のスキルとの関係を鳥瞰図で示すクレイジーな HTML5/KineticJS アクションを作成します。

現在、以下のコードはうまく機能しており、一貫して 5 レベルの深さをマップしています。

delegate :url_helpers, to: 'Rails.application.routes'

def prereqs_map
  prereqs_array = [ self.title.to_s, url_helpers.skill_path(self), Array.new(prereqs) ]
  prereqs_array[2] = prereqs_array[2].map do |prereq1|
    prereq1 = [ prereq1.title.to_s, url_helpers.skill_path(prereq1), Array.new(prereq1.prereqs).map do |prereq2|
      prereq2 = [ prereq2.title.to_s, url_helpers.skill_path(prereq2), Array.new(prereq2.prereqs).map do |prereq3|
        prereq3 = [ prereq3.title.to_s, url_helpers.skill_path(prereq3), Array.new(prereq3.prereqs).map do |prereq4|
          prereq4 = [ prereq4.title.to_s, url_helpers.skill_path(prereq4), Array.new(prereq4.prereqs).map do |prereq5|
            prereq5 = [ prereq5.title.to_s, url_helpers.skill_path(prereq5), [] ]
          end ] # prereq depth 5
        end ] # prereq depth 4
      end ] # prereq depth 3
    end ] # prereq depth 2
  end   # prereq depth 1

  return prereqs_array
end

ご覧のとおり、問題は、ネストされたマップが非常に面倒であり、depthパラメーターを渡して、渡した深さにメソッドをマップする方法を理解する方法がないことです。

これを行うにはもっと良い方法が必要だと思います。何かご意見は?

4

2 に答える 2

2

これを試して:

class Skill
  # has many prereqs?

  def prereqs_map(depth = 5)
    mapping = Proc.new do |node, depth, current_level|
      [node.title.to_s, url_helpers.skill_path(node), node.prereqs.map {|prereq| mapping.call(prereq, depth, current_level+1)}] if current_level <= depth
    end
    mapping.call(self, depth, 0)
  end

end

>> skill.prereqs_map(5)
于 2012-12-30T18:00:50.920 に答える
1

インスタンスメソッド「to_tree」をモデルに追加することで、それを再帰できます。以下は、依存関係のツリーをランダムに設定し、必要な形式で配列の配列を提供します。

class Skill

  attr_accessor :prereqs
  attr_accessor :title

  def randomly_create_tree depth=0
    self.title = ["Coding", "Winning", "Smiling", "Eating"][rand(4)]
    if depth < 3
      self.prereqs = []
      (0..rand(3)).each do
        skill = Skill.new
        skill.randomly_create_tree(depth + 1)
        self.prereqs << skill
      end
    else
      self.prereqs = []
    end
    self
  end

  def to_tree
    prereqs.collect do |prereq|
      [self.title, prereq.to_tree]
    end
  end

その後:

s = Skill.new
s.randomly_create_tree
s.to_tree

結果:

[["Coding", [["Winning", [["Winning", []], ["Winning", []]]]]]] 

各文字列はランダムに生成されたタイトルです。おそらく url_helpers.skill_path も追加したいと思うでしょうが、それが何をするのかわかりません。

于 2012-12-30T17:56:30.007 に答える