From: gregarican Date: 2007-09-10T03:15:10+09:00 Subject: Re: Combining Array Elements On Aug 26, 12:26 pm, Robert Klemme wrote: > On 24.08.2007 23:40, Stefan Rusterholz wrote: > > > > > > > Greg Kujawa wrote: > >> On Aug 24, 9:52 am, "Robert Klemme" > >> 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- 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 :-)