RoR / Ruby 删除嵌套数组中的空元素

14

要将一个数组分成两个相等的部分,我会这样做:

>> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
>> a.in_groups_of( (a.size/2.0).ceil ) if a.size > 0
=> [[1, 2, 3], [4, 5, nil]]

现在我有一个嵌套的数组,如果数组大小为奇数,则包含nil元素。如何从嵌套数组中删除nil元素?我想做的事情是:

a.compact

不幸的是,这并不起作用,Ruby只会在第一层级别上删除nil元素,而不是递归地删除。 Ruby是否提供了解决此问题的好方法?

5个回答

44

在Ruby 1.8.7及更高版本中,您可以执行以下操作:

a.each &:compact!
=> [[1, 2, 3], [4, 5]]

在 Ruby 1.8.6 中,您需要以较长的方式执行此操作:

a.each {|s| s.compact!}

这两者都会修改a的内容。如果你想返回一个新数组并保留原数组不受影响,可以使用collect而不是each

# 1.8.7+:
a.collect &:compact

# 1.8.6:
a.collect {|s| s.compact}

3
我认为 & 语法是在1.8.7版本中引入的。 - EmFi
1
@EmFi 很好的观点 - 我忘记了1.8.7。我会编辑我的回答。 - Phil Ross
你也可以使用 a.map(&:compact) - Bongs

8
如果您使用in_groups_of,可以将false作为第二个参数传递给它,它将不会用nil填充“空白”,而是真正的什么都不填。

3
除非您想永久更改 a,否则请不要这样做。
a.map do |e|
  e.compact
end

0
arr_mixed=['hello', 2222, 'world', nil, [1, 2, 5, 'hi', nil],[1, 2, 3], [4,   5, nil]]

def compact_nested(array)
   arr2=[]
   array.each { |x|
   element = x.class==Array ? x.compact : x
   arr2<<element
   }
   arr2
end

p compact_nested(arr_mixed).compact #=>["hello", 2222, "world", [1, 2, 5, "hi"], [1, 2, 3], [4, 5]]
p arr_mixed #=>["hello", 2222, "world", nil, [1, 2, 5, "hi", nil], [1, 2, 3], [4, 5, nil]]

-3
a.each {|subarray| subarray.compact!}
a.compact!

应该可以工作……


2
可能不值得回复过期的帖子,但这两行应该相反。如果我们假设anil,那么我们应该先压缩它,否则我们将在块内获得nil错误。 - NIA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接