Combining Array Elements

I have an array that I would like to combine elements. Here's a sample
array:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
Value B", 1]]

What I would like to do is find the elements where the first two items
are the same and then combine the third. The resulting array would
consist of:

[["Value A", "Value B", 4],["Value A", "Value C", 2]]

This is something that is out in left field in terms of how I've used
arrays in the past. Anyone know of a quick bit of script I can whip up
that will suit the task?

gregarican wrote:

I have an array that I would like to combine elements. Here's a sample
array:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
Value B", 1]]

What I would like to do is find the elements where the first two items
are the same and then combine the third. The resulting array would
consist of:

[["Value A", "Value B", 4],["Value A", "Value C", 2]]

This is something that is out in left field in terms of how I've used
arrays in the past. Anyone know of a quick bit of script I can whip up
that will suit the task?
  

new_array = array.collect{|v| [v[0],v[1], a.select{|b| b[0] == v[0] && b[1] == v[1] }.inject(0){|m,b| m + b.last}]}.uniq

gregarican wrote:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
Value B", 1]]

What I would like to do is find the elements where the first two items
are the same and then combine the third.

arr=[["Value A", "Value B", 3], ["Value A", "Value C", 2],
    ["Value A", "Value B", 1]]
arr.inject(Hash.new 0) do |hash, sarr|
  hash[sarr[0..-2]] += sarr[-1]
  hash
end #=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}

Not exactly what you asked for, but converting it into an array shouldn't be
too hard from there.

···

--
NP: Ensiferum - Treacherous Gods
Ist so, weil ist so
Bleibt so, weil war so

irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
"Value C", 2],["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):002:0> hash = Hash.new(0)
=> {}
irb(main):003:0> orig_array.each { |elem| hash[ elem[0,2] ] +=
elem[2] }
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):004:0> hash.collect { |k, v| k + [v] }
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

or, more concisely

irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
"Value C", 2],["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):002:0> orig_array.inject(Hash.new(0)) { |hash, elem|
hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

···

On Aug 24, 7:50 am, gregarican <greg.kuj...@gmail.com> wrote:

I have an array that I would like to combine elements. Here's a sample
array:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
Value B", 1]]

What I would like to do is find the elements where the first two items
are the same and then combine the third. The resulting array would
consist of:

[["Value A", "Value B", 4],["Value A", "Value C", 2]]

This is something that is out in left field in terms of how I've used
arrays in the past. Anyone know of a quick bit of script I can whip up
that will suit the task?

--
-yossef

Hi --

gregarican wrote:

I have an array that I would like to combine elements. Here's a sample
array:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
Value B", 1]]

What I would like to do is find the elements where the first two items
are the same and then combine the third. The resulting array would
consist of:

[["Value A", "Value B", 4],["Value A", "Value C", 2]]

This is something that is out in left field in terms of how I've used
arrays in the past. Anyone know of a quick bit of script I can whip up
that will suit the task?

new_array = array.collect{|v| [v[0],v[1], a.select{|b| b[0] == v[0] && b[1]

                                             ^^^^^^^^
You mean array.select, I think.

== v[1] }.inject(0){|m,b| m + b.last}]}.uniq

This is just a cosmetic change, but you could do:

new_array = array.map {|v,w| [v,w, array.select {|b,c|
   b == v && c == w }.inject(0){|m,b| m + b.last}]}.uniq

or even:

new_array = array.map {|v,w| [v,w, array.select {|b,c|
   [b,c] == [v,w] }.inject(0){|m,b| m + b.last}]}.uniq

David

···

On Fri, 24 Aug 2007, Jeremy Wells wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

I believe there is an even simpler solution:

irb(main):001:0> arr=[["Value A", "Value B", 3], ["Value A", "Value
C", 2], ["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]

irb(main):003:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)| ha[[a,b]]+=c;ha}
=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}

irb(main):004:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.inject() {|re,v| re<<v.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

Of course, the most elegant solution uses #inject - in this case two
injects. :slight_smile:

Although, this one might be even better:

irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.map {|x| x.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

At least 1 #inject. :slight_smile:

Kind regards

robert

···

2007/8/24, Yossef Mendelssohn <ymendel@pobox.com>:

On Aug 24, 7:50 am, gregarican <greg.kuj...@gmail.com> wrote:
> I have an array that I would like to combine elements. Here's a sample
> array:
>
> [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
> Value B", 1]]
>
> What I would like to do is find the elements where the first two items
> are the same and then combine the third. The resulting array would
> consist of:
>
> [["Value A", "Value B", 4],["Value A", "Value C", 2]]
>
> This is something that is out in left field in terms of how I've used
> arrays in the past. Anyone know of a quick bit of script I can whip up
> that will suit the task?

irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
"Value C", 2],["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):002:0> hash = Hash.new(0)
=> {}
irb(main):003:0> orig_array.each { |elem| hash[ elem[0,2] ] +=
elem[2] }
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):004:0> hash.collect { |k, v| k + [v] }
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

or, more concisely

irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
"Value C", 2],["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]
irb(main):002:0> orig_array.inject(Hash.new(0)) { |hash, elem|
hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

Thanks guys. All of the insight helps me out tremendously. There are a
lot of abilities that I never tapped into along these lines. Great
stuff and hopefully more tools in my belt. Appreciate the tips!

···

On Aug 24, 9:52 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:

2007/8/24, Yossef Mendelssohn <ymen...@pobox.com>:

> On Aug 24, 7:50 am, gregarican <greg.kuj...@gmail.com> wrote:
> > I have an array that I would like to combine elements. Here's a sample
> > array:

> > [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
> > Value B", 1]]

> > What I would like to do is find the elements where the first two items
> > are the same and then combine the third. The resulting array would
> > consist of:

> > [["Value A", "Value B", 4],["Value A", "Value C", 2]]

> > This is something that is out in left field in terms of how I've used
> > arrays in the past. Anyone know of a quick bit of script I can whip up
> > that will suit the task?

> irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
> "Value C", 2],["Value A", "Value B", 1]]
> => [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
> "Value B", 1]]
> irb(main):002:0> hash = Hash.new(0)
> => {}
> irb(main):003:0> orig_array.each { |elem| hash[ elem[0,2] ] +=
> elem[2] }
> => [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
> "Value B", 1]]
> irb(main):004:0> hash.collect { |k, v| k + [v] }
> => [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

> or, more concisely

> irb(main):001:0> orig_array = [["Value A", "Value B", 3], ["Value A",
> "Value C", 2],["Value A", "Value B", 1]]
> => [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
> "Value B", 1]]
> irb(main):002:0> orig_array.inject(Hash.new(0)) { |hash, elem|
> hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }
> => [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

I believe there is an even simpler solution:

irb(main):001:0> arr=[["Value A", "Value B", 3], ["Value A", "Value
C", 2], ["Value A", "Value B", 1]]
=> [["Value A", "Value B", 3], ["Value A", "Value C", 2], ["Value A",
"Value B", 1]]

irb(main):003:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)| ha[[a,b]]+=c;ha}
=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}

irb(main):004:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.inject() {|re,v| re<<v.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

Of course, the most elegant solution uses #inject - in this case two
injects. :slight_smile:

Although, this one might be even better:

irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.map {|x| x.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

At least 1 #inject. :slight_smile:

Kind regards

robert- Hide quoted text -

- Show quoted text -

Greg Kujawa wrote:

> > [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
> > that will suit the task?
> "Value B", 1]]
> hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }
=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}
irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.map {|x| x.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

At least 1 #inject. :slight_smile:

Kind regards

robert- Hide quoted text -

- Show quoted text -

Thanks guys. All of the insight helps me out tremendously. There are a
lot of abilities that I never tapped into along these lines. Great
stuff and hopefully more tools in my belt. Appreciate the tips!

What makes me slightly sad is that all those examples try to squeeze as
much as possible into a single statement. Frankly, in my opinion the
resulting code is horrible to read again a few months later.
I'll try to go a different way, a bit more to type but hopefully easier
to read. Maybe somebody has an even more readable idea.

array = [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value
A", "Value B", 1]]
groups = array.group_by { |element| element.first(2) }
result = groups.map { |key, values|
  values.map! { |a,b,c| c } # if I knew what each value represents I'd
chose better names
  key+[values.sum]
}

# required code (group_by is in 1.9, though probably a different
implementation, sum is in activesupport afaik)
module Enumerable
  def group_by(result=nil, add=nil)
    result ||= Hash.new { |h,k| h[k]= }
    add ||= :<<
    each { |args| result[yield(args)].__send__(add, args) }
    result
  end
end

module Enumerable
  def sum
    inject(0) { |a,b| a+b }
  end
end

Regards
Stefan

···

On Aug 24, 9:52 am, "Robert Klemme" <shortcut...@googlemail.com> > wrote:

--
Posted via http://www.ruby-forum.com/\.

Yet another variation on the theme:
def foo(a)
  a.inject(Hash.new(0)) { |h, (k1, k2, v)| lambda { |k|
h.update(k=>h[k]+v) }[[k1,k2]] }.map { |k, v| k + [v] }
end

# What makes me slightly sad is that all those examples try to
# squeeze as much as possible into a single statement. Frankly,
# in my opinion the resulting code is horrible to read again a few
# months later.

# array = [["Value A", "Value B", 3], ["Value A", "Value C",
# 2],["Value A", "Value B", 1]]
# groups = array.group_by { |element| element.first(2) }
# result = groups.map { |key, values|
# values.map! { |a,b,c| c }
# key+[values.sum]
# }

glad you mention group_by :slight_smile: anyone who's been making reports and transposing rows/columns can see its value.

i think we can still squeeze to one line and still be readable, now that you mention group_by.

note that i modified your sum. i like passing what i want to add.

eg,

a

=> [["A", "B", 3], ["A", "C", 2], ["A", "B", 1]]

a.group_by{|x|x.first(2)}

=> {["A", "B"]=>[["A", "B", 3], ["A", "B", 1]], ["A", "C"]=>[["A", "C", 2]]}

basically, we get the key, then merge the sum of the last elements
thus,

a.group_by{|x|x.first(2)}.map{|x,y| x<<y.sum{|z|z.last}}

=> [["A", "B", 4], ["A", "C", 2]]

or

a.group_by{|x|x.first(2)}.map{|x,y| x+[y.sum{|z|z.last}]}

=> [["A", "B", 4], ["A", "C", 2]]

or just use plain inject instead of sum

a.group_by{|x|x.first(2)}.map{|x,y|x<<y.inject(0){|sum,z|sum+z.last}}

=> [["A", "B", 4], ["A", "C", 2]]

kind regards -botp

···

From: Stefan Rusterholz [mailto:apeiros@gmx.net]

Greg Kujawa wrote:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
that will suit the task?

"Value B", 1]]
hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }

=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}
irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.map {|x| x.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

At least 1 #inject. :slight_smile:

Kind regards

robert- Hide quoted text -

- Show quoted text -

Thanks guys. All of the insight helps me out tremendously. There are a
lot of abilities that I never tapped into along these lines. Great
stuff and hopefully more tools in my belt. Appreciate the tips!

What makes me slightly sad is that all those examples try to squeeze as much as possible into a single statement.

That was not my primary concern. I tried to avoid pasting lengthy IRB screen copies as they tend to look horrible. The code could have been on more lines as well.

Frankly, in my opinion the resulting code is horrible to read again a few months later.

I'd say: it depends. People seem to be quite different with regard to their "readability ranking". I know people who prefer shorter code. Since this is not production code and especially without explicit comments (there's always the mail / news thread) it's not intended to be easily readable after a longer period of time.

I'll try to go a different way, a bit more to type but hopefully easier to read. Maybe somebody has an even more readable idea.

array = [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A", "Value B", 1]]
groups = array.group_by { |element| element.first(2) }
result = groups.map { |key, values|
  values.map! { |a,b,c| c } # if I knew what each value represents I'd chose better names
  key+[values.sum]
}

What I dislike about this solution is that it traverses the collection twice although it is more modular. If I want very readable code I'd do something like this:

array = ...
groups = Hash.new 0
array.each do |(a,b,c)|
p a
   groups[[a,b]] += c
end
result = groups.to_a

# required code (group_by is in 1.9, though probably a different implementation, sum is in activesupport afaik)
module Enumerable
  def group_by(result=nil, add=nil)
    result ||= Hash.new { |h,k| h[k]= }
    add ||= :<<
    each { |args| result[yield(args)].__send__(add, args) }
    result
  end
end

Personally I would not make the Hash and add an argument here because there are too many requirements. (I.e. result needs to guarantee that result will return something that can receive the method you use).

module Enumerable
  def sum
    inject(0) { |a,b| a+b }
  end
end

Note that this implementation of sum only works for numeric types. It does not work for example for string concatenation.

Kind regards

  robert

···

On 24.08.2007 23:40, Stefan Rusterholz wrote:

On Aug 24, 9:52 am, "Robert Klemme" <shortcut...@googlemail.com> >> wrote:

I just picked up this thread again. I can concur about the readability
factor, in that if I've picked up my own relatively uncommented code a
few months later it can be hard to read. Especially if it's terser
Perlish stuff. But like regular expressions, if I dig into it for a
bit I can pick up how I did what I needed to do. Usually as a rule I
go back in and heavily comment terser areas of my programming.

Wanted to thank everyone who contributed to different ways to
accomplish this one task. I am using my script to help the jewelry
company I work for price out and keep sufficient on-hand quanities of
loose diamonds. Each stone goes into its own category due to carat,
cut, color, and clarity and I have to parse through all of the
inventory to glead out what goes where. This Ruby script has
eliminated hours of data entry and analysis manually punching things
into an Excel spreadsheet. Now my script goes that work for them
through the array/hash manipulation and through win32ole. Gotta love
Ruby and the Ruby community :slight_smile:

···

On Aug 26, 12:26 pm, Robert Klemme <shortcut...@googlemail.com> wrote:

On 24.08.2007 23:40, Stefan Rusterholz wrote:

> Greg Kujawa wrote:
>> On Aug 24, 9:52 am, "Robert Klemme" <shortcut...@googlemail.com> > >> wrote:
>>>>> [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
>>>>> that will suit the task?
>>>> "Value B", 1]]
>>>> hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }
>>> => {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}
>>> irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
>>> ha[[a,b]]+=c;ha}.map {|x| x.flatten}
>>> => [["Value A", "Value C", 2], ["Value A", "Value B", 4]]

>>> At least 1 #inject. :slight_smile:

>>> Kind regards

>>> robert- Hide quoted text -

>>> - Show quoted text -
>> Thanks guys. All of the insight helps me out tremendously. There are a
>> lot of abilities that I never tapped into along these lines. Great
>> stuff and hopefully more tools in my belt. Appreciate the tips!

> What makes me slightly sad is that all those examples try to squeeze as
> much as possible into a single statement.

That was not my primary concern. I tried to avoid pasting lengthy IRB
screen copies as they tend to look horrible. The code could have been
on more lines as well.

> Frankly, in my opinion the
> resulting code is horrible to read again a few months later.

I'd say: it depends. People seem to be quite different with regard to
their "readability ranking". I know people who prefer shorter code.
Since this is not production code and especially without explicit
comments (there's always the mail / news thread) it's not intended to be
easily readable after a longer period of time.

> I'll try to go a different way, a bit more to type but hopefully easier
> to read. Maybe somebody has an even more readable idea.

> array = [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value
> A", "Value B", 1]]
> groups = array.group_by { |element| element.first(2) }
> result = groups.map { |key, values|
> values.map! { |a,b,c| c } # if I knew what each value represents I'd
> chose better names
> key+[values.sum]
> }

What I dislike about this solution is that it traverses the collection
twice although it is more modular. If I want very readable code I'd do
something like this:

array = ...
groups = Hash.new 0
array.each do |(a,b,c)|
p a
   groups[[a,b]] += c
end
result = groups.to_a

> # required code (group_by is in 1.9, though probably a different
> implementation, sum is in activesupport afaik)
> module Enumerable
> def group_by(result=nil, add=nil)
> result ||= Hash.new { |h,k| h[k]= }
> add ||= :<<
> each { |args| result[yield(args)].__send__(add, args) }
> result
> end
> end

Personally I would not make the Hash and add an argument here because
there are too many requirements. (I.e. result needs to guarantee that
result will return something that can receive the method you use).

> module Enumerable
> def sum
> inject(0) { |a,b| a+b }
> end
> end

Note that this implementation of sum only works for numeric types. It
does not work for example for string concatenation.

Kind regards

        robert- Hide quoted text -

- Show quoted text -

Hey, that sounds like a great success story! I'm glad, Ruby could make your life a lot easier, because that's what I believe Ruby is about.

Kind regards

  robert

···

On 09.09.2007 20:14, gregarican wrote:

On Aug 26, 12:26 pm, Robert Klemme <shortcut...@googlemail.com> wrote:

On 24.08.2007 23:40, Stefan Rusterholz wrote:

Greg Kujawa wrote:

On Aug 24, 9:52 am, "Robert Klemme" <shortcut...@googlemail.com> >>>> wrote:

[["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value A",
that will suit the task?

"Value B", 1]]
hash[ elem[0,2] ] += elem[2]; hash }.collect { |k, v| k + [v] }

=> {["Value A", "Value C"]=>2, ["Value A", "Value B"]=>4}
irb(main):007:0> arr.inject(Hash.new(0)) {|ha,(a,b,c)|
ha[[a,b]]+=c;ha}.map {|x| x.flatten}
=> [["Value A", "Value C", 2], ["Value A", "Value B", 4]]
At least 1 #inject. :slight_smile:
Kind regards
robert- Hide quoted text -
- Show quoted text -

Thanks guys. All of the insight helps me out tremendously. There are a
lot of abilities that I never tapped into along these lines. Great
stuff and hopefully more tools in my belt. Appreciate the tips!

What makes me slightly sad is that all those examples try to squeeze as
much as possible into a single statement.

That was not my primary concern. I tried to avoid pasting lengthy IRB
screen copies as they tend to look horrible. The code could have been
on more lines as well.

Frankly, in my opinion the
resulting code is horrible to read again a few months later.

I'd say: it depends. People seem to be quite different with regard to
their "readability ranking". I know people who prefer shorter code.
Since this is not production code and especially without explicit
comments (there's always the mail / news thread) it's not intended to be
easily readable after a longer period of time.

I'll try to go a different way, a bit more to type but hopefully easier
to read. Maybe somebody has an even more readable idea.
array = [["Value A", "Value B", 3], ["Value A", "Value C", 2],["Value
A", "Value B", 1]]
groups = array.group_by { |element| element.first(2) }
result = groups.map { |key, values|
  values.map! { |a,b,c| c } # if I knew what each value represents I'd
chose better names
  key+[values.sum]
}

What I dislike about this solution is that it traverses the collection
twice although it is more modular. If I want very readable code I'd do
something like this:

array = ...
groups = Hash.new 0
array.each do |(a,b,c)|
p a
   groups[[a,b]] += c
end
result = groups.to_a

# required code (group_by is in 1.9, though probably a different
implementation, sum is in activesupport afaik)
module Enumerable
  def group_by(result=nil, add=nil)
    result ||= Hash.new { |h,k| h[k]= }
    add ||= :<<
    each { |args| result[yield(args)].__send__(add, args) }
    result
  end
end

Personally I would not make the Hash and add an argument here because
there are too many requirements. (I.e. result needs to guarantee that
result will return something that can receive the method you use).

module Enumerable
  def sum
    inject(0) { |a,b| a+b }
  end
end

Note that this implementation of sum only works for numeric types. It
does not work for example for string concatenation.

Kind regards

        robert- Hide quoted text -

- Show quoted text -

I just picked up this thread again. I can concur about the readability
factor, in that if I've picked up my own relatively uncommented code a
few months later it can be hard to read. Especially if it's terser
Perlish stuff. But like regular expressions, if I dig into it for a
bit I can pick up how I did what I needed to do. Usually as a rule I
go back in and heavily comment terser areas of my programming.

Wanted to thank everyone who contributed to different ways to
accomplish this one task. I am using my script to help the jewelry
company I work for price out and keep sufficient on-hand quanities of
loose diamonds. Each stone goes into its own category due to carat,
cut, color, and clarity and I have to parse through all of the
inventory to glead out what goes where. This Ruby script has
eliminated hours of data entry and analysis manually punching things
into an Excel spreadsheet. Now my script goes that work for them
through the array/hash manipulation and through win32ole. Gotta love
Ruby and the Ruby community :slight_smile:

It's quite disappointing that this is being used for diamonds. How
marvelously meta it would have been if Ruby had been used for
rubies. :slight_smile:

···

On Sep 9, 12:14 pm, gregarican <greg.kuj...@gmail.com> wrote:

Wanted to thank everyone who contributed to different ways to
accomplish this one task. I am using my script to help the jewelry
company I work for price out and keep sufficient on-hand quanities of
loose diamonds. Each stone goes into its own category due to carat,
cut, color, and clarity and I have to parse through all of the
inventory to glead out what goes where. This Ruby script has
eliminated hours of data entry and analysis manually punching things
into an Excel spreadsheet. Now my script goes that work for them
through the array/hash manipulation and through win32ole. Gotta love
Ruby and the Ruby community :slight_smile: