如何在一个方法内循环?

问题描述:

我想在Rails应用程序的方法中添加一个循环。它看起来像这样如何在一个方法内循环?

Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    child[0]: "child_url" 
) 

有时父母没有孩子。有时父母会有x个孩子。我如何在一个循环遍历所有这些孩子的函数中创建一个循环。

我想是这样

i=0 
children=Child.all 
Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    for child in children 
    child[i]: "child_url" 
    i= i + 1 
    end 
) 

,将产生

Parent.do_something(
     attribute: "a string", 
     parameter: "a string", 
     child[0]: "child_0_url", 
     child[1]: "child_1_url", 
     child[2]: "child_2_url" 
    ) 

如果我没有解释的很清楚这个问题,我会更新基于评论我的问题。

+0

你真的需要每个孩子的钥匙吗?或者你只是想获得一个child_urls数组? – 2013-04-23 04:01:50

+0

你究竟想要完成什么?现在它看起来像你试图添加一个可变数量的条目到散列然后传递给类方法 – AJcodez 2013-04-23 04:05:38

+0

是的,我需要每个条目的一个键。我已经更新了这个问题,对不清楚的道歉,我正在努力解决这个问题(甚至是否有可能) – 2013-04-23 04:20:05

正如其他人所建议的,它可能是更好的重新设计方法来期望一组孩子,而不是大量的单个参数:

Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    children: ["child_0_url", "child_1_url", "child_2_url"] 
) 

但是,如果你有做到这一点,你说的方式(例如,如果你被别人约束别人的API差):

children = Child.all 
Parent.do_something(
    {attribute: "a string", 
    parameter: "a string"}.merge Hash[*(children.each_with_index.map { |child, i| ["child[#{i}]", child.url] }.flatten)] 
) 

丑陋的,是吧?俗话说得好;如果很难做到,你可能做错了。 Ismael Abreu的答案的平面地图非常漂亮。

+0

同意你这很丑陋,绝对不是我喜欢的方法,但这正是我需要的答案。谢谢! – 2013-04-23 14:38:34

可能会更容易的部分提取到一个不同的方法:

Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    children: children_method 
) 

def children_method 
    Parent.children.map do |child| 
    # whatever needs to be done 
    end 
end 

你可能只是想这样做:

children = Child.all 
Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    child: children.map { |child| child.url } 
) 
+0

+1假设'child.url'是有效的。希望它给OP提供了足够的有关如何正确使用map的信息。 – Phrogz 2013-04-23 04:09:28

+0

感谢您的建议。然而,我需要生成可变数量的子对象,即'child [0]:xxxxx,child [1]:yyyyyy,child [2]:.....'这是引起我混淆的部分! – 2013-04-23 04:18:39

+0

这给你的东西就像'child:[xxx,yyy]'。你仍然有相同的数据,但在一个数组中,所以你可以更容易地访问它。你可能不熟悉'map'方法,它基本上允许你创建一个新的数组,对当前数组的元素进行操作,应用你提供给它的块。在这种情况下,我调用了一个孩子的url方法(我只是假设有这样的方法),然后我得到一个相同顺序的孩子网址数组。 – 2013-04-23 04:50:41

如果你想在喜欢的网址你输入他们,试试这个:

children = Child.all 
Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    child: something 
) 

def something 
    child = [] 
    children.length.times { |index| child << "child_#{index}_url"} 
    return child 
end 

你也可以更换Child.count children.length如果你不需要在其他地方的孩子,但我假设你做。

编辑:我想这可能是越多,你在找什么

children = Child.all 
Parent.do_something(
    attribute: "a string", 
    parameter: "a string", 
    child: children.each_with_index.map { |child,i| "child_#{i}_#{child.url}"} 
) 

这需要的,如果没有块被赋予each_with_index返回一个枚举的事实。

如果您尝试将可变数量的参数传递给某个方法,那么您可能正在寻找splat (*) operator

+0

这是一个有用的提示!不完全是我在这里寻找的东西,但无论如何都很好学习。 – 2013-04-23 14:45:28