From: Ross Bamford Date: 2006-03-30T07:41:32+09:00 Subject: Re: How to interator over two arrays? On Thu, 2006-03-30 at 03:13 +0900, baumanj@gmail.com wrote: > Ross Bamford wrote: > > Notice OP wanted to sum or multiply each element *resulting in a new > > array of summed elements*. Other solutions posted injected an array: > > > > arr.zip(brr).inject([]) { |ary,(a,b)| ary << a + b } > > Ah yes, but if you look at the original post, you'll see that what he's > actually calculating is the dot product (a single value) and that his > code returns a single value (assuming he defined the sum method): > Okay, I didn't look too deeply beyond the first example (of the array that was wanted, a[0] + b[0], a[1] + b[1], ..., a[n] + a[n]) so I didn't realise about the exact nature of what was needed. I don't think it makes a real difference to how you'd code it, though...? Anyway, assuming the sum method is defined, he could just do: sum(arr.zip(brr).map! { |a,b| a * b }) :) > So despite what he said, it appears what he actually wants is inject. > If so, the first response is correct: > > Dave Burt wrote: > > dotproduct = doc.zip(query).inject(0) {|sum, (d, q)| sum + d * q } > As I said, I wasn't suggesting any incorrectness in the posted solutions, just adding a footnote on a general point. I do now see that inject was the way to go in this particular case. > The zip solution you posted isn't quite right, because it creates an > array of the sums of the elements rathar than the products and doesn't > produce the actual dot product value. I think what you meant was: > > arr.zip(brr).inject([]) { |ary,(a,b)| ary << a * b } > > But that just generates the array of products, not their sum. If both > the value and the array of products are required, I don't think there's > a one-line solution without getting really ugly. Yes, I suppose I did mean that. Perhaps I should have quoted directly rather than paraphrasing. And it probably depends on your definition of ugly (and of 'one-line' too I guess), but if both were needed you could do: ary = [1,2,3,4,5] bry = [1,2,3,4,5] s,*p = ary.zip(bry).inject([0]) {|arr,(a,b)| arr[0]+=(p=a*b) and arr< 55 p p # => [1, 4, 9, 16, 25] -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk