我有一行代码迭代数组并拒绝所有空元素:
survey.reject!(&:empty?).map! { |feedback| %(_"#{feedback}"_) }
如果整个数组为空,则按预期工作。如果数组中的某个元素不为空,则会出现错误map!
不存在。
然而,这没有问题:
survey.map! { |feedback| %(_"#{feedback}_") }
当整个数组为空时reject
函数有效,而当数组不为空时map!
版本有效。我怎样才能最好地巩固这些?
答案 0 :(得分:4)
使用就地修饰符时必须小心。正如the documentation for reject!
says:
删除块评估为{em> true 的
self
的每个元素,如果未进行任何更改,则返回nil
。
由于该功能,您不能像可以复制的版本那样链接这些。
你可以做的是两行:
survey.reject!(&:empty?)
survey.map! { |feedback| %(_"#{feedback}"_) }
或者你可以重新分配:
survey = survey.reject(&:empty?).map { |feedback| %(_"#{feedback}"_) }
答案 1 :(得分:3)
Array#reject!
如果没有更改任何内容,则会返回nil
。 nil
没有map!
方法,因此您获得NoMethodError
。
为什么还要链接副作用方法?副作用方法的目的是它的副作用,而不是它的返回值。你可以做到
survey.reject!(&:empty?)
survey.map! { |feedback| %(_"#{feedback}"_) }
或者,更好的是:不要使用副作用。他们是邪恶的。
survey = survey.reject(&:empty?).map { |feedback| %(_"#{feedback}"_) }
但是,请注意,不执行与上述操作相同的操作:上述操作会使survey
的引用的单个对象发生变异。这会改变引用survey
本身并使其指向不同的对象。
整体上这个更干净,但如果你的系统中有其他代码依赖于可变的共享状态和副作用,那么它也必须改变。