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. :-) >>> >>> 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