3

I can't seem to find an algorithm to compute the number of arrays within an array. Example

Given

[ [ "Array", "1" ], [ "Array", "2" ] ]

Output should be two

Given

[
    [
        [ ["Array", "1"], ["Array", "2"] ],
        [ ["Array", "3"], ["Array", "4"] ],
    ],
    [
        [ ["Array", "5"], ["Array", "6"] ],
        [ ["Array", "7"], ["Array", "8"] ]
    ]
]`

Output should be 8

1
  • 1
    How about [ [ [ ["Arr", "1"], ["Arr", "2"] ], [ ["Arr", "3"] ] ], [ ["Arr", "4"], ["Arr", "5"] ] ] ? Commented Mar 5, 2012 at 8:27

3 Answers 3

5

This recursive function will do the job for arrays of any nesting:

def count_subarrays array
  return 0 unless array && array.is_a?(Array)

  nested = array.select { |e| e.is_a?(Array) }
  if nested.empty?
    1 # this is a leaf
  else
    nested.inject(0) { |sum, ary| sum + count_subarrays(ary) }
  end
end
Sign up to request clarification or add additional context in comments.

Comments

0

I suggest that you use a recursion function which would return 1 if the argument is a leaf array, for example: (if there are two children in each array as in the saas course exercise)

 def array?(entity)
    entity[0].kind_of?(Array) ? array?(entity[0]) + array?(entity[1]) : 1
 end

2 Comments

Your choice for a method name is quite questionable, especially so since it ends in ? (which typically would imply it returns a boolean) yet returns a number.
Further, this doesn't account for the case where there are anything other than exactly two elements that are both arrays, or the first element is not an array.
0
class Array
  def deep_array_count()
    count = 0
    each{|el|
      #I could check with is_a?(Array), but with respond_to? you could use your own classes.
      if el.respond_to?(:deep_array_count)            
        count += 1 + el.deep_array_count
      end
    }
    count
  end
end

x = [
   [
     [
      ["Array", "1"], ["Array", "2"] ],
     [ ["Array", "3"], ["Array", "4"] ],
   ],
   [
     [ ["Array", "5"], ["Array", "6"] ],
     [ ["Array", "7"], ["Array", "8"] ]
   ]
  ]

 p x.deep_array_count 

The result in this example is 14, not your requested 8. I count each array.

To get the 8 you must count only arrays without another array.

class Array
  def deep_array_count()
    count = 0
    each{|el|
      #I could check with is_a?(Array), but with respond_to? you could use your own classes.
      if el.respond_to?(:deep_array_count)            
        i = el.deep_array_count
        count += i == 0 ? 1 : i #if no other array is inside, add 1
      end
    }
    count
  end
end

x = [
   [
     [
      ["Array", "1"], ["Array", "2"] ],
     [ ["Array", "3"], ["Array", "4"] ],
   ],
   [
     [ ["Array", "5"], ["Array", "6"] ],
     [ ["Array", "7"], ["Array", "8"] ]
   ]
  ]

 p x.deep_array_count 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.