统计 Int 可选类型数组中 nil 值的数量

4

我是一个刚开始接触Swift并且正在使用可选项的人。在使用generateRandomArrayOfIntsAndNils()函数后,我很难统计测试数组中nil的数量。

这是我要尝试的方法:

let array1: [Int?]
array1 = generateRandomArrayOfIntsAndNils()\

var total = 0

for i in array1 {
    if(array1[i] == nil){
    total += 1
    }
}

print(total)

任何建议或指导都将不胜感激。

谢谢大家的回复! - bck
如果某个答案对您有帮助,您应该将其标记为已接受。 - Connor Neville
4个回答

10

你可以这样做:

let countNils = array1.filter({ $0 == nil }).count

4

计算nil值的数量

使用for case ...

除了已经提到的函数式方法之外,您还可以使用for case ... in循环来有条件地增加total计数器。

let arr = [1, nil, 3, 4, nil, 6] // [Int?] inferred

var numberOfNilValues = 0
for case .none in arr { numberOfNilValues += 1 }
print(numberOfNilValues) // 2

使用for ... where

或者,另一种方式是将for循环与where子句结合起来进行条件递增:

let arr = [1, nil, 3, 4, nil, 6]

var numberOfNilValues = 0
for e in arr where e == nil { numberOfNilValues += 1 }
print(numberOfNilValues) // 2

计算非nil值的数量

值得明确提到,我们可以类似上面的for case ...方法,来计算那些不是nil(即.some)的值的数量:

let arr = [1, nil, 3, 4, nil, 6]

var numberOfNonNilValues = 0
for case .some in arr { numberOfNonNilValues += 1 }
print(numberOfNonNilValues) // 4

在这种情况下,我们也可以使用简写(通配符可选模式)_?形式:
var numberOfNonNilValues = 0
for case _? in arr { numberOfNonNilValues += 1 }
print(numberOfNonNilValues) // 4

2
巧妙地利用语言特性:for casefor ... where - Code Different
现在我可以回复你的评论了 Another tribute to the explicit loops :) - 这些似乎是目前发布的所有解决方案中最快的。 - Martin R
@MartinR 嘿嘿,谢谢;我们一直回到了好老的(调整过的)显式循环 :) 啊,我自己没有对它们进行基准测试,但我怀疑reduce和显式循环方法会更快;奇怪的是,在发布模式下,reduce与上面的方法不可比,但也许编译器还没有完全到位。 - dfrib

2
更加高效,因为不需要创建一个包含所有 nil 的中间数组:
let array1: [Int?] = [1,2,3,nil,nil]
let nilCount = array1.reduce(0) { $0 + ($1 == nil ? 1 : 0) }

print(nilCount) // 2

工作原理:

  • reduce从初始值开始迭代数组中的每个元素
  • 我们从0开始计数
  • 如果元素为nil,则将1添加到运行总数中($ 0为运行总数,$ 1为当前元素)

1
还有一个愚蠢的替代方法:let nilCount = array1.reduce(0) { $0 + ($1.map { _ in 0 } ?? 1) } :) - dfrib
@Sulthan,我上面评论中提到的替代方法与此答案中的方法以相同的方式对数组进行折叠,但使用了(愚蠢的)可选的 map 调用而不是三元运算符来进行条件增加。 - dfrib
@Sulthan 这样做会破坏答案的“高效”声明,因为它构建了一个中间数组。 - Code Different
1
@dfri 我们可能可以考虑一些更傻的替代方案 :) - Sulthan
1
@dfri 我想到了 NSCountedSet(array: array1).count(for: nil as Int?) - Sulthan
显示剩余2条评论

0

愚蠢解决方案竞赛的下一个解决方案 :)

说明:flatMap移除了空值:

let arr = [1, nil, 3, 4, nil, 6]

print(arr.count - arr.flatMap{$0}.count 
// 2

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