I have an array that contains the following: 114,151,157,151,10,12,14,151,157,10 I need to count how many instances of each item show up in this string. In this case: 114 shows up 1 time 151 shows up 3 times 157 shows up 2 times 10 shows up 2 times 12 shows up 1 time 14 shows up 1 time From there I need to match it back up so I can define this in an orderly fashion. Ala: counted151 = "3", counted157 = "2", counted10 = "2", counted114 = "1", counted14 = "1", counted12 = "1", If you haven''t guessed by now this only my 12th hour using RoR, so the code that I have so far simply creates the array and does a .length method for a count variable. I have a feeling this job requires array.map and I''ve been playing around with that method but I still cant be certain as to how to implement it. Any tips or ideas would be greatly appreciated. In the meantime I''ll keep at it. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ricky Kilmer wrote:> I have an array that contains the following: > > 114,151,157,151,10,12,14,151,157,10 > > I need to count how many instances of each item show up in this string. > In this case: > > 114 shows up 1 time > 151 shows up 3 timesI bet someone can find an even leaner way than this: $ irb > array = [114,151,157,151,10,12,14,151,157,10] > counts = {} > array.each{|cell| counts[cell] = 0 } > array.each{|cell| counts[cell] += 1 } > p counts {12=>1, 151=>3, 14=>1, 157=>2, 114=>1, 10=>2} Ruby is really great for tiny expressions that do a lot. (And I used ''cell'' because your data structure is a histogram...) -- Phlip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Apr 5, 5:25 am, Phlip <phlip2...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I bet someone can find an even leaner way than this:Now you''ve said that I''ve got to!> $ irb > > array = [114,151,157,151,10,12,14,151,157,10] > > counts = {} > > array.each{|cell| counts[cell] = 0 } > > array.each{|cell| counts[cell] += 1 } > > p counts >array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} Using a default value for the hash means you only need to iterate over it once. Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Phlip wrote:> Ricky Kilmer wrote: > >> I have an array that contains the following: >> >> 114,151,157,151,10,12,14,151,157,10 >> >> I need to count how many instances of each item show up in this string. >> In this case: >> >> 114 shows up 1 time >> 151 shows up 3 times > > I bet someone can find an even leaner way than this: > > $ irb > > array = [114,151,157,151,10,12,14,151,157,10] > > counts = {} > > array.each{|cell| counts[cell] = 0 } > > array.each{|cell| counts[cell] += 1 } > > p counts > > {12=>1, 151=>3, 14=>1, 157=>2, 114=>1, 10=>2} > > Ruby is really great for tiny expressions that do a lot. (And I used > ''cell'' > because your data structure is a histogram...) > > -- > PhlipThat did the trick. And I was able to sort it nicely with: p counts.sort {|a,b| -1*(a[1]<=>b[1]) } Frederick Cheung wrote:> On Apr 5, 5:25�am, Phlip <phlip2...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> I bet someone can find an even leaner way than this: > Now you''ve said that I''ve got to! > >> $ irb >> �> array = [114,151,157,151,10,12,14,151,157,10] >> �> counts = {} >> �> array.each{|cell| counts[cell] = 0 } >> �> array.each{|cell| counts[cell] += 1 �} >> �> p counts >> > array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} > Using a default value for the hash means you only need to iterate over > it once. > > FredThat didn''t seem to work for me and I''m not sure why, probably because to be honest I don''t know what your line actually does. What does the semicolon do?: array = [114,151,157,151,10,12,14,151,157,10] array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} puts hash outputs an unknown integer. More likely than not, I am not executing it correctly. Thanks for the tips guys. You should have seen the mess I was trying to build with .map and counts lol. I cant wait to get as good as you. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 5 Apr 2008, at 16:53, Ricky Kilmer wrote:> > array = [114,151,157,151,10,12,14,151,157,10] > array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} > puts hash > > outputs an unknown integer. More likely than not, I am not executing > it > correctly. >inject returns the value you want, so result = array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} puts result would do what you want What inject does is take an initial value, and pass that and each element of the collection to the block, and then updates the initial value with the result of the block. So for example, you can rewrite the sum function as array.inject(0) {|memo, value| memo = value} The semicolon is just to keep everything on the same line, because i need the result of the block to be memo. Fred> > Thanks for the tips guys. You should have seen the mess I was trying > to > build with .map and counts lol. I cant wait to get as good as you. > -- > Posted via http://www.ruby-forum.com/. > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> > That did the trick. And I was able to sort it nicely with: > > p counts.sort {|a,b| -1*(a[1]<=>b[1]) } >Just as a note here, you could sort it as: p counts.sort {|a,b| b[1]<=>a[1] } Which might be a little more obvious to someone reading the code. (I was confused by the -1*( ) on first glance )> > That didn''t seem to work for me and I''m not sure why, probably because > to be honest I don''t know what your line actually does. What does the > semicolon do?: > > array = [114,151,157,151,10,12,14,151,157,10] > array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} > puts hash > > outputs an unknown integer. More likely than not, I am not executing it > correctly.The semi colon is a statement seperator. It lets you have multiple ruby statements on a line. In this case, it''s there so that the second ''line'' (memo) returns the hash to the block so that it can be used again. Inject works by iterating over the collection (array), giving the block the current result (memo) and the current item (value) from the collection. At the end of each invocation of the block, result is set to the return value of the block, which is the return value of the last statement evaluated. A variable on it''s own, like memo, returns the variable itself, so we construct that over the course of the iterations, and then return it at the end. The block works for me, though the hash which is constructed is the return value, so line should be counts = array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} p counts hth, Jon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
@Rick I can name that tune in two lines: array = [114,151,157,151,10,12,14,151,157,10] array.group_by{|val| val}.each{|val, occurs| puts "#{val} occurs #{occurs.size} times"} On Apr 5, 5:33 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Apr 5, 5:25 am, Phlip <phlip2...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I bet someone can find an even leaner way than this: > > Now you''ve said that I''ve got to! > > > $ irb > > > array = [114,151,157,151,10,12,14,151,157,10] > > > counts = {} > > > array.each{|cell| counts[cell] = 0 } > > > array.each{|cell| counts[cell] += 1 } > > > p counts > > array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} > Using a default value for the hash means you only need to iterate over > it once. > > Fred--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jonathan Stott wrote:>> >> That did the trick. And I was able to sort it nicely with: >> >> p counts.sort {|a,b| -1*(a[1]<=>b[1]) } >> > > Just as a note here, you could sort it as: > > p counts.sort {|a,b| b[1]<=>a[1] } > > Which might be a little more obvious to someone reading the code. (I > was confused by the -1*( ) on first glance ) > >> correctly. > The semi colon is a statement seperator. It lets you have multiple ruby > statements on a line. In this case, it''s there so that the second > ''line'' (memo) returns the hash to the block so that it can be used > again. > > Inject works by iterating over the collection (array), giving the block > the current result (memo) and the current item (value) from the > collection. At the end of each invocation of the block, result is set > to the return value of the block, which is the return value of the last > statement evaluated. A variable on it''s own, like memo, returns the > variable itself, so we construct that over the course of the iterations, > and then return it at the end. > > The block works for me, though the hash which is constructed is the > return value, so line should be > > counts = array.inject(Hash.new(0)) {|memo, value| memo[value]+=1; memo} > > p counts > > hth, > JonAhh. Not only do I see where I went wrong on executing it, but I understand how it works. You are right about sorting, it can be ascending values .sort {|a,b| a[1]<=>b[1] } or descending values .sort {|a,b| -1*(a[1]<=>b[1]) } -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> Phlip wrote: > >> I bet someone can find an even leaner way than this: > Now you''ve said that I''ve got to!Thanks! Even though raw Ruby is best served on news:comp.lang.ruby , not here! (-: -- Phlip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> > You are right about sorting, it can be ascending values > > .sort {|a,b| a[1]<=>b[1] } > > or descending values > > .sort {|a,b| -1*(a[1]<=>b[1]) }You can also sort descending via: .sort {|a,b| b[1]<=>a[1] } (note the swapped ''a'' and ''b'') as I said in the previous email. (Although multiplying the result by -1 also works, yes) Jon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jonathan Stott wrote:> .sort {|a,b| b[1]<=>a[1] } > > (note the swapped ''a'' and ''b'') as I said in the previous email.Note also that many sorts with the spaceship operator <=> can simplify with sort_by: .sort_by{|a| -a[1] } -- Phlip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---