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

问题描述 投票:4回答:3

最常见的方法是从几个没有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不一定要考虑。变量是真值(数字/字符串/数组/哈希)或nil

arrays ruby
3个回答
4
投票

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


2
投票

我希望有一种方法可以在数组创建过程中以某种方式“跳过” 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

这会将代码移到其他地方。

一切都是对象

从面向对象的角度来看,nil没什么特别的-它是与其他对象一样的对象。因此,删除nil与删除1没有区别。

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

关于“优点或缺点”:

[[...] withcompact/ compact!

  • 创建完整数组并根据需要缩小它
  • 短代码,通常适合一行
  • 易于识别
  • 每个项目评估一次
  • 更快(编译的C代码)

[[...]<<if语句

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

判决:

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


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)轻松删除。

© www.soinside.com 2019 - 2024. All rights reserved.