Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over digits of integers inside of array

Tags:

arrays

loops

ruby

I have this code below:

 a = [435,276,434]

 def product(a)
   final = 1
   for e in a
     for p in a[e]
       final*=p
     end
   end
   final
 end

 puts product(a)

I'm wondering how I can iterate over this array twice where the result is 4*3*5 = 60, 2*7*6 = 85, and 4*3*4 = 48

I wrote some code up above which I thought would do the trick here but Ruby keeps on returning an error.

like image 459
Jamaal Avatar asked Dec 02 '25 04:12

Jamaal


1 Answers

A few points to consider:

In Ruby you basically never use a for loop to iterate over things. #each is better. You get to pass a block to that, which gives you all kinds of room for flexibility and expressiveness.

Also, you can't - normally - iterate over an Integer. Remember that an Integer is a store of numerical value, not a particular representation, so it would have to be dependent on the base of the representation you wanted. If you want a string of characters, each of which happen to be numbers, well, guess what? You want a String, like seph's solution here. Or an Array, which would probably make even more sense because each integer would remain an integer and wouldn't have to be parsed back and forth.

Tell you what, let's build a really cool method to do this and staple this on to Integer, and hopefully demonstrate some of Ruby's cool features.

class Integer
  include Enumerable
  def each(base = 10, &blk)
    front, back = abs.divmod(base)
    if front > 0
      front.each(base, &blk)
    end
    yield back
  end
end

This little number takes a base and a block, gets the absolute value of the integer (since technically the minus isn't a digit), then uses divmod to split the number, chopping off the final digit. We store the pieces in front and back. We check to see if there are any more digits, indicated by front being 0, and if there is we recursively call this method, with that block. Then we just yield the back, sending the digit to the block.

Since we have now defined an each method, we are now free to include Enumerable which gets us a ton of stuff!

As long as that modification is active, your product method becomes:

(if you wanted to print 60 84 48): a.map {|n| n.reduce(:*)}

(or if you wanted to print 241920): a.reduce(:*).reduce(:*)

Pretty nice!

So, this total solution is quite a bit longer than seph's one-liner, and in truth if I needed to actually do something I would just to_s. Is my solution quicker to execute? Who knows? It's certainly more expressive, though, and that's why you're using Ruby in the first place.

If you want to solve a problem, yeah, absolutely, to_s. But if you want your code to express a philosophy you have about numbers, about how really they're just collections too - and they are, in a weird set theory kind of way, Ruby lets you empower them to be that. And this way that doesn't need Strings at all, they're totally free of their grudging assistance. And you can iterate through different bases, which is super useful if you're doing hex or binary, which preserves more of the numbery essence of them.

In this world that you and I have built together, Jamaal, little integers run wild through the forests with the big boys. And that's wonderful.

like image 124
Leon Spencer Avatar answered Dec 04 '25 17:12

Leon Spencer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!