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<<p}

p s
# => 55

p p
# => [1, 4, 9, 16, 25]

-- 
Ross Bamford - rosco / roscopeco.REMOVE.co.uk