对于不同数量的数组,如何创建具有不同深度的嵌套FOR循环?

时间:2009-11-07 19:55:33

标签: ruby

我在一个巨大的数组中有不同数量的数组。这是正确的方法吗?:

parentArray = [[array],[array2],....]

如何为每个连续数组创建一系列嵌套循环,以便在前一个数组中创建数组循环?

parentArray.each do |eacharray|

    array.each do |eacharray1|
     array2.each do |eacharray2|
      array3.each do |eacharray3|
       arrayN.each do ....
         .....
          .....

     ...
    ...
   end    
  end
 end
end

示例:

网络蜘蛛将访问包含链接的第一页,并将其存储为数组。蜘蛛访问第一页上的第一个链接,并在此级别发现更多链接,并将其存储为数组。蜘蛛继续前进并不断发现越来越多的链接,直到它达到最深层次。

我最终得到了:

rootArray = [arrayLinks, arrayLink2, arrayLinks3....]

执行.flatten会破坏所有深度关系。

我需要的是一个递归(树?)例程,它将执行一个递归嵌套循环,从第一个数组开始,AKA arrayLinks,并在第一个数组中构建另一个循环,依此类推。

@Justice,基本上我有很多阵列。第一个数组是“父”,然后下一个数组是“父”的每个值的子元素。如果有另一个数组,则它将是前一个数组的每个值的子项。

6 个答案:

答案 0 :(得分:1)

如果您关心的是为所有级别运行相同的指令,那么您可以简单地flatten数组(使其成为一维)然后运行您的指令:

parentArray.flatten.each do |element|
   puts element
end

这将递归地将所有尺寸展平为单个尺寸。我相信这只适用于Ruby 1.9及更高版本。

答案 1 :(得分:1)

我使用递归解决了类似的问题。

def processArrays(parents, arrs)
  if not arrs.empty?
    a0 = arrs[0]
    parents.push(a0)
    a0.each {|a0x| processArrays(parents, arrs[1..-1])
    parents.pop
  end
end

你用processArrays([], topArray)调用它,每个级别都有父数组(到目前为止)和一组剩余的数组可以使用。

答案 2 :(得分:1)

    parentArray = [[1,2],[3,4,['alpha','beta']],'a','b','c']

def processArray(array,depth)
  array.each do |element|
       if element.is_a?(Array)
          processArray(element,depth+1)
       else
          puts "Element at Depth #{depth.to_s} is #{element.to_s}"
       end
  end
end


processArray(parentArray,1)

此输出:

Element at Depth 2 is 1
Element at Depth 2 is 2
Element at Depth 2 is 3
Element at Depth 2 is 4
Element at Depth 3 is alpha
Element at Depth 3 is beta
Element at Depth 1 is a
Element at Depth 1 is b
Element at Depth 1 is c

答案 3 :(得分:1)

问题:为parentArray中的每个数组创建嵌套循环= [[array1],[array2],....]

a = [[1,2,3],[:a,:b],[:X,:Z]]
a.first.product(*a.drop(1)).each do |i|
  i.size.times {|p| printf("i[%d]=%s ",p,i[p])}
  puts
end

结果:

i[0]=1 i[1]=a i[2]=X
i[0]=1 i[1]=a i[2]=Z 
i[0]=1 i[1]=b i[2]=X
i[0]=1 i[1]=b i[2]=Z 
i[0]=2 i[1]=a i[2]=X 
i[0]=2 i[1]=a i[2]=Z 
i[0]=2 i[1]=b i[2]=X 
i[0]=2 i[1]=b i[2]=Z 
i[0]=3 i[1]=a i[2]=X 
i[0]=3 i[1]=a i[2]=Z 
i[0]=3 i[1]=b i[2]=X 
i[0]=3 i[1]=b i[2]=Z 

答案 4 :(得分:0)

我创建了一个脚本,假定内部循环被重写为名为innerloop(arrayOfCurrentValues)的方法。每次运行时都要调用该方法,每次传递的数组都包含每个嵌套循环中当前选定的值,按顺序从最外层循环到最内层循环。

此处的数组a是您的parentArray

这是代码和演示:

Script started on Sat Nov  7 21:55:40 2009
bash-3.2$ cat loops.rb
a = [[1,2,3],[:a,:b],[51,52,53,54]]

def innerloop(arrayOfCurrentValues)
  puts "innerloop("+arrayOfCurrentValues.inspect+")"
end

def traverse(accumulated,params, index) 
 if (index==params.size)
  return innerloop(accumulated) 
 end

 currentParam = params[index]
 currentParam.each do |currentElementOfCurrentParam|
  traverse(accumulated+[currentElementOfCurrentParam],params, index+1)
 end

end


traverse([],a,0)



bash-3.2$ ruby loops.rb
innerloop([1, :a, 51])
innerloop([1, :a, 52])
innerloop([1, :a, 53])
innerloop([1, :a, 54])
innerloop([1, :b, 51])
innerloop([1, :b, 52])
innerloop([1, :b, 53])
innerloop([1, :b, 54])
innerloop([2, :a, 51])
innerloop([2, :a, 52])
innerloop([2, :a, 53])
innerloop([2, :a, 54])
innerloop([2, :b, 51])
innerloop([2, :b, 52])
innerloop([2, :b, 53])
innerloop([2, :b, 54])
innerloop([3, :a, 51])
innerloop([3, :a, 52])
innerloop([3, :a, 53])
innerloop([3, :a, 54])
innerloop([3, :b, 51])
innerloop([3, :b, 52])
innerloop([3, :b, 53])
innerloop([3, :b, 54])
bash-3.2$ exit
exit

Script done on Sat Nov  7 21:55:51 2009

答案 5 :(得分:0)

module Scratch
  def self.recur(arr, depth, &fn)
    arr.each do |a| 
      a.is_a?(Array) ?  recur(a, depth+1, &fn) : fn.call(a, depth)
    end
  end
  arr = [[1, 2, 3], 4, 5, [6, 7, [8, 9]]]
  recur(arr, 0) { |x,d| puts "#{d}: #{x}" }
end