Hash sanitization from query - newbie

I need to clean up a hash

[{0=>"BSD", 1=>105, "Operating System"=>"BSD", "count(*)"=>105},
{0=>"SUSE", 1=>99, "Operating System"=>"SUSE", "count(*)"=>99},
{0=>"Ubuntu", 1=>97, "Operating System"=>"Ubuntu", "count(*)"=>97},
{0=>"Unix", 1=>190, "Operating System"=>"Unix", "count(*)"=>190},
{0=>"Windows XP", 1=>92, "Operating System"=>"Windows XP",
"count(*)"=>92}]

You'll notice the first part is an array key value pair and the second
part of each hash is a real key value pair.

How would I go about removing all the 0=> and 1=> references from the
above hash?

I've seen people use inject and map but are a bit lost with regards to
those functions.

···

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

# class Hash - RDoc Documentation

oses = [
  {0=>"BSD", 1=>105, "Operating System"=>"BSD", "count(*)"=>105},
  {0=>"SUSE", 1=>99, "Operating System"=>"SUSE", "count(*)"=>99},
  {0=>"Ubuntu", 1=>97, "Operating System"=>"Ubuntu", "count(*)"=>97},
  {0=>"Unix", 1=>190, "Operating System"=>"Unix", "count(*)"=>190},
  {0=>"Windows XP", 1=>92, "Operating System"=>"Windows XP","count(*)"=>92}
]

oses.each do |os|
  os.delete 0
  os.delete 1
end

require 'pp'
pp oses
# >> [{"Operating System"=>"BSD", "count(*)"=>105},
# >> {"Operating System"=>"SUSE", "count(*)"=>99},
# >> {"Operating System"=>"Ubuntu", "count(*)"=>97},
# >> {"Operating System"=>"Unix", "count(*)"=>190},
# >> {"Operating System"=>"Windows XP", "count(*)"=>92}]

···

On Tue, Feb 8, 2011 at 1:27 PM, Sem Ptiri <rubyforum@chthonic.co.za> wrote:

I need to clean up a hash

[{0=>"BSD", 1=>105, "Operating System"=>"BSD", "count(*)"=>105},
{0=>"SUSE", 1=>99, "Operating System"=>"SUSE", "count(*)"=>99},
{0=>"Ubuntu", 1=>97, "Operating System"=>"Ubuntu", "count(*)"=>97},
{0=>"Unix", 1=>190, "Operating System"=>"Unix", "count(*)"=>190},
{0=>"Windows XP", 1=>92, "Operating System"=>"Windows XP",
"count(*)"=>92}]

You'll notice the first part is an array key value pair and the second
part of each hash is a real key value pair.

How would I go about removing all the 0=> and 1=> references from the
above hash?

oses = [
{0=>"BSD", 1=>105, "Operating System"=>"BSD", "count(*)"=>105},
{0=>"SUSE", 1=>99, "Operating System"=>"SUSE", "count(*)"=>99},
{0=>"Ubuntu", 1=>97, "Operating System"=>"Ubuntu", "count(*)"=>97},
{0=>"Unix", 1=>190, "Operating System"=>"Unix", "count(*)"=>190},
{0=>"Windows XP", 1=>92, "Operating System"=>"Windows XP","count(*)"=>92}
]

# map version

oses.map{|h| h.delete_if{|k,_| k==0 or k==1}}

#=> [{"Operating System"=>"BSD", "count(*)"=>105}, {"Operating
System"=>"SUSE", "count(*)"=>99}, {"Operating System"=>"Ubuntu",
"count(*)"=>97}, {"Operating System"=>"Unix", "count(*)"=>190},
{"Operating System"=>"Windows XP", "count(*)"=>92}]

# inject version

oses.inject(){|a,h| a << h.delete_if{|k,_| k==0 or k==1} }
#=> [{"Operating System"=>"BSD", "count(*)"=>105}, {"Operating
System"=>"SUSE", "count(*)"=>99}, {"Operating System"=>"Ubuntu",
"count(*)"=>97}, {"Operating System"=>"Unix", "count(*)"=>190},
{"Operating System"=>"Windows XP", "count(*)"=>92}]

but note, you have repeating keys wc could be just be fields themselves, eg

oses.map{|h| h.delete_if{|k,_| k==0 or k==1}; h.values}
#=> [["BSD", 105], ["SUSE", 99], ["Ubuntu", 97], ["Unix", 190],
["Windows XP", 92]]

or

Hash[ *oses.map{|h| h.delete_if{|k,_| k==0 or k==1}; h.values}.flatten ]
#=> {"BSD"=>105, "SUSE"=>99, "Ubuntu"=>97, "Unix"=>190, "Windows XP"=>92}

best regards -botp

···

On Wed, Feb 9, 2011 at 3:27 AM, Sem Ptiri <rubyforum@chthonic.co.za> wrote:

I've seen people use inject and map but are a bit lost with regards to
those functions.

Thanks for the comparisons.

···

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

If I have the following:

[[148,"Uneducated"],[135,"Highschool"],[272,"Some
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]

is there an function to invert/swap the numbers with strings?

···

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

irb(main):001:0> [[148,"Uneducated"],[135,"Highschool"],[272,"Some
irb(main):002:2"
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]].each
{|a| a.reverse!}
=> [["Uneducated", 148], ["Highschool", 135], ["Some\ncollege", 272],
["University", 141], ["Post-grad", 143], ["PhD", 144], ["other", 141],
["Post-doc", 8]]

Btw, for your original problem there is an elegant solution which has
not been shown yet:

irb(main):003:0> [{0=>"BSD", 1=>105, "Operating System"=>"BSD",
"count(*)"=>105},
irb(main):004:1* {0=>"SUSE", 1=>99, "Operating System"=>"SUSE", "count(*)"=>99},
irb(main):005:1* {0=>"Ubuntu", 1=>97, "Operating System"=>"Ubuntu",
"count(*)"=>97},
irb(main):006:1* {0=>"Unix", 1=>190, "Operating System"=>"Unix",
"count(*)"=>190},
irb(main):007:1* {0=>"Windows XP", 1=>92, "Operating System"=>"Windows XP",
irb(main):008:2* "count(*)"=>92}].each {|h| h.delete_if {|k,| Integer === k}}
=> [{"Operating System"=>"BSD", "count(*)"=>105}, {"Operating
System"=>"SUSE", "count(*)"=>99}, {"Operating System"=>"Ubuntu",
"count(*)"=>97}, {"Operating System"=>"Unix", "count(*)"=>190},
{"Operating System"=>"Windows XP", "count(*)"=>92}]

Although you have to consider that this works only if you do not have
numeric keys that you want to keep.

Cheers

robert

···

On Tue, Feb 15, 2011 at 10:51 AM, Sem Ptiri <rubyforum@chthonic.co.za> wrote:

If I have the following:

[[148,"Uneducated"],[135,"Highschool"],[272,"Some
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]

is there an function to invert/swap the numbers with strings?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Maybe I misunderstand what you are trying to do here, but what about
something like:

studies = [[148,"Uneducated"],[135,"Highschool"],[272,"Some
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]

studies.map(&:reverse)
=> [["Uneducated", 148], ["Highschool", 135], ["Some college", 272],
["University", 141], ["Post-grad", 143], ["PhD", 144], ["other", 141],
["Post-doc", 8]]

···

--
Estanislau Trepat

http://twitter.com/etrepat

2011/2/15 Sem Ptiri <rubyforum@chthonic.co.za>

If I have the following:

[[148,"Uneducated"],[135,"Highschool"],[272,"Some

college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]

is there an function to invert/swap the numbers with strings?

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

Take a look at map or map! (if you want to modify the object in place):

irb(main):005:0> a = [[148,"Uneducated"],[135,"Highschool"],[272,"Some
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]
=> [[148, "Uneducated"], [135, "Highschool"], [272, "Some college"],
[141, "University"], [143, "Post-grad"], [144, "PhD"], [141, "other"],
[8, "Post-doc"]]
irb(main):006:0> a.map {|(num,string)| [string,num]}
=> [["Uneducated", 148], ["Highschool", 135], ["Some college", 272],
["University", 141], ["Post-grad", 143], ["PhD", 144], ["other", 141],
["Post-doc", 8]]

Jesus.

···

On Tue, Feb 15, 2011 at 10:51 AM, Sem Ptiri <rubyforum@chthonic.co.za> wrote:

If I have the following:

[[148,"Uneducated"],[135,"Highschool"],[272,"Some
college"],[141,"University"],[143,"Post-grad"],[144,"PhD"],[141,"other"],[8,"Post-doc"]]

is there an function to invert/swap the numbers with strings?