从Ruby中没有nil值的变量创建数组

时间:2015-09-17 07:27:28

标签: arrays ruby

从没有nil值的多个变量创建数组的最常用方法是什么?

鉴于这些变量:

a = 1
b = nil
c = 3

我想创建一个数组ary

ary #=> [1, 3]

我可以使用Array#compact

ary = [a, b, c].compact
ary #=> [1, 3]

但是将所有内容放在数组中只是为了删除某些元素后感觉不对。

另一方面,使用if语句会产生更多代码:

ary = []
ary << a if a
ary << b if b
ary << c if c
ary #=> [1, 3]

是否存在其他或首选方式或使用上述任何一种方法有任何优点或缺点?

PS:false并不一定要考虑。变量是truthy(数字/字符串/数组/哈希)或nil

3 个答案:

答案 0 :(得分:3)

如果您担心性能,最好的方法可能是使用破坏性#compact!来避免为第二个数组分配内存。

答案 1 :(得分:1)

我希望在数组创建过程中以某种方式“跳过”nil值。但是在考虑了一段时间之后,我意识到由于Ruby处理多个值的方法,这无法实现。没有值“列表”的概念,多个值总是表示为数组。

如果您指定多个值,Ruby会创建一个数组:

ary = 1, nil, 3
#=> [1, nil, 3]

采用可变数量参数的方法相同:

def foo(*args)
  args
end

foo(1, nil, 3)
#=> [1, nil, 3]

因此,即使我使用类方法Array修补new_without_nil,我最终还是会选择:

def Array.new_without_nil(*values)
  values.compact!
  values
end

这只是将代码移到别处。

一切都是对象

从OO的角度来看,nil并没有什么特别之处 - 它就像其他任何对象一样。因此,删除nil与删除1没有区别。

另一方面,使用一堆if语句是我在编写面向对象代码时要避免的。我更喜欢向对象发送消息。

关于“优点或缺点”:

[...]compact / compact!

  • 创建完整数组并根据需要缩小它
  • 短代码,通常适合一行
  • 很容易识别
  • 评估每个项目
  • 更快(已编译的C代码)
带有[...]<<声明的

if

  • 创建空数组并根据需要增长
  • 长代码,每个项目一行
  • 目的可能不那么明显
  • 项目可以轻松注释/取消注释
  • 评估每个项目两次
  • 慢(解释Ruby代码)

判决:

我会使用compact,可能很明显。

答案 2 :(得分:0)

这是使用哈希的解决方案。

将这些值放入数组中

a = 1; b = nil; c = 3; d = nil; e = 10;
ary = [a, b, c, d, e]

结果中有两个零项,需要compact才能删除两个“零”项。

但是将相同的变量添加到哈希中:

a = 1; b = nil; c = 3; d = nil; e = 10;
hash = {a => nil, b => nil, c => nil, d => nil, e => nil}

结果中只有一个“零”项可以被hash.delete(nil)轻松删除。