0

I have an array of hashes, like this:

my_array = [{foo:1,bar:"hello",baz:3},{foo:2,bar:"hello2",baz:495,foo_baz:"some_string"},...] 
#there can be arbitrary many in this list.
#There can also be arbitrary many keys on the hashes.

I want to create a new array that is a copy of the last array, except that I remove any :bar entries.

my_array2 = [{foo:1,baz:3},{foo:2,baz:495,foo_baz:"some_string"},...]

I can get the my_array2 by doing this:

my_array2 = my_array.map{|h| h.delete(:bar)}

However, this changes the original my_array, which I want to stay the same.

Is there a way of doing this without having to duplicate my_array first?

5
  • are you using active_support? Commented May 8, 2014 at 14:11
  • Just a note: duplicating an array wouldn't help :) Commented May 8, 2014 at 14:13
  • @BroiSatse I found that out actually. Commented May 8, 2014 at 20:22
  • @Cort3z - Just one more note: You will end up with a new array with new hashes regardless of whether you use dup or not. Those are however a shallow copies, so they won't use too much additional memory. Commented May 8, 2014 at 21:25
  • Yeah, they should be reference only, which is ok for me. The reason why I don't want to do deep copy is that the stuff in my hash is potentially very big (strings of length 1000+). Commented May 8, 2014 at 21:32

2 Answers 2

5

one of many ways to accomplish this:

my_array2 = my_array.map{|h| h.reject{|k,v| k == :bar}}
Sign up to request clarification or add additional context in comments.

6 Comments

beat me by 21 secs :)
I would say Hash#reject is purpose-built for this. One tiny detail: I would make reject's block variables |k,_| to emphasize the fact you are only using the key (as I see @Santosh has done).
@CarySwoveland: Two small questions: Why is reject better than select? Is it faster, or is it simply readability? And: same question for the _. Faster or just pretty?
Sorry for misleading you, Cortt3z. reject and select are more-or-less equivalent here, as both must check all the elements. I was poking fun at @Santosh, suggesting he chose select only because Philipp had used reject.
Ahh.. hehe, get it. Funny that I selected the reject ^^ But really tough, the _. I remember reading something about that a long time ago. Is it faster, or just pretty? I would guess it is a bit faster if it does not have to allocate any variables for each element.
|
2
my_array.map {|h| h.select{|k, _| k != :bar} }
# => [{:foo=>1, :baz=>3}, {:foo=>2, :baz=>495, :foo_baz=>"some_string"}]

1 Comment

I would say 21 seconds counts as a tie. +1 for both of you. reject is so much better though. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.