开发者

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]
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜