How can I improve the code to delete items in an array in the following case?
I have this 开发者_运维知识库code:
array = ['notice', 'warning', 'error']
array.delete('notice') if flash[:notice]
array.delete('warning') if flash[:warning]
array.delete('error') if flash[:error]
Since there are repeated names, in order to shorten the code, I could use the interpolation to perform this part of code:
array.delete('notice') if flash[:notice]
array.delete('warning') if flash[:warning]
array.delete('error') if flash[:error]
How can I do that in one step?
I tryed this
array.each { |item|
array.delete("#{item}") if flash[:"#{item}"]
}
but it doesn't work good.
array.reject! { |item| flash[item.to_sym] }
That happens because you're modifying array over which you iterate.
Something like this should work
array.clone.each { |item|
array.delete("#{item}") if flash[:"#{item}"]
}
Try running it with and without clone
on sample input
array = ['notice', 'warning', 'error']
flash = {:warning => 1, :error => 2}
...
p array
But there's no need to invoke delete
manually, you can just user reject:
array = array.reject! { |item| flash[:"#{item}"] }
You don't need to use string interpolation, just convert the strings to symbols using .to_sym
:
array = ['notice', 'warning', 'error']
array.each { |item|
array.delete(item) if flash[item.to_sym]
}
Or use symbols in array
to .to_s
in the delete:
array = [:notice, :warning, :error]
array.each { |item|
array.delete(item.to_s) if flash[item]
}
精彩评论