coyote_rey
coyote_rey

Reputation: 31

Remove everything after first whitespace in array

I have an array of hashes with some values inside the hashes containing spaces. I would like to run through every array element and every value within the hashes to remove any spaces and the following characters past the space. An example of my data would be

arrayHash = [{:firstname=>'Anne Marie', :lastname=>'Hook', :email=>'[email protected]', :id=>1}, 
           {:firstname=>'Michael', :lastname=>'Rodriguez', :email=>'[email protected]', :id=>2}]

So for example on the firstname key, I would like to take 'Anne Marie' and reduce it to just 'Anne', and do the same for every element in this array.

Upvotes: 2

Views: 130

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110675

If you wish to mutate arrayHash, you could do the following:

arrayHash.each { |h| h.each { |k,v| h[k] = v.is_a?(String) ? v[/\A\S*/] : v } }
  #=> [{:firstname=>"Anne", :lastname=>"Hook", :email=>"[email protected]", :id=>1},
  #    {:firstname=>"Michael", :lastname=>"Rodriguez", :email=>"[email protected]", :id=>2}] 

arrayHash is mutated:

arrayHash
  #=> [{:firstname=>"Anne", :lastname=>"Hook", :email=>"[email protected]", :id=>1},
  #    {:firstname=>"Michael", :lastname=>"Rodriguez", :email=>"[email protected]", :id=>2}] 

The regex /\A\S*/ matches the beginning of the string followed by zero or more characters other than whitespace. For the string v, v[/\A\S*/] returns the match. (See the method String#[]).

If you do not wish to mutate arrayHash, this is one way:

arrayHash.map { |h| h.merge(h) { |_,v,_| v.is_a?(String) ? v[/\A\S*/] : v } }
  #=> [{:firstname=>"Anne", :lastname=>"Hook", :email=>"[email protected]", :id=>1},
  #    {:firstname=>"Michael", :lastname=>"Rodriguez", :email=>"[email protected]", :id=>2}] 

arrayHash is unchanged:

arrayHash
  #=> [{:firstname=>"Anne Marie", :lastname=>"Hook", :email=>"[email protected]", :id=>1},
  #    {:firstname=>"Michael", :lastname=>"Rodriguez", :email=>"[email protected]", :id=>2}] 

In the second case I've used the form of the method Hash#merge which employs a block to determine the values of keys that are present in both hashes being merged, which here is all the keys. See the doc for an explanation of the values of the three block variables (the first and third of which I've represented with an underscore to signify that they are not used in the block calculation).

Upvotes: 3

Andrey Deineko
Andrey Deineko

Reputation: 52357

arrayHash.map! do |hash|
  hash.each_with_object({}) do |(k, v), h|
    h[k] = v.is_a?(String) ? v.split(' ').first : v
  end
end
#=>[{:firstname=>"Anne", :lastname=>"Hook", :email=>"[email protected]", :id=>1}, {:firstname=>"Michael", :lastname=>"Rodriguez", :email=>"[email protected]", :id=>2}]

Upvotes: 3

Related Questions