迭代 NSSet 并强制转换为一步到位

Posted

技术标签:

【中文标题】迭代 NSSet 并强制转换为一步到位【英文标题】:Iterate NSSet and cast to type in one step 【发布时间】:2016-04-30 11:08:29 【问题描述】:

有没有办法从 NSSet(或任何非本地 Swift 集合)中转换元素,并一步将每个元素转换为一种类型。目前我正在这样做

// "zoo" is an NSOrderedSet
for animal in zoo 
  if let animal = animal as? Animal 
    if animal.needFeeding 
      // Feed the animal
    
  

上面看起来有点笨拙。该集合来自 CoreData,所以我必须使用 NSSet。

【问题讨论】:

如果集合来自 Core Data,它应该有一个唯一的类型,所以类型检查可能是可有可无的。 @vadian:这确实是一个好点! 【参考方案1】:

您可以在for 循环中使用模式匹配case let

for case let animal as Animal in zoo  
    if animal.needFeeding 

    

请注意,这只会跳过不是 (一个子类)Animal

【讨论】:

为什么不用for case let animal as Animal in zoo where animal.needFeeding ... 呢? ;-) @vadian:当然!我只是想回答“如何一步完成迭代和投射”的问题。以后可能还会将更多语句添加到循环中。 (实际上我不确定我更喜欢哪个版本的易读性。)【参考方案2】:

为了完整性,NSOrderedSet 只是集合和数组的组合,您可以使用其中任何一个进行迭代,将其转换为 Swift SetArray 类型:

for animal in zoo.set as! Set<Animal> 
    if animal.needFeeding 
    

for animal in zoo.array as! [Animal] 
    if animal.needFeeding 
    

【讨论】:

这个解决方案可以工作,但 case 选项是最好的,因为集合可能包含动物以外的其他项目。【参考方案3】:

对于 NSOrderedSet 等,我会像这样安全地循环映射内容:

for animal in zoo.flatMap( $0 as? Animal ) 
    if animal.needFeeding 
        // Feed the animal
    

啊,当然,有一个类似的问答......我已经回答了类似的问题。不过,另一个有更多选择:https://***.com/a/35558210/2227743

【讨论】:

以上是关于迭代 NSSet 并强制转换为一步到位的主要内容,如果未能解决你的问题,请参考以下文章

将迭代器强制转换为另一种类型

如何在不强制转换为数字的情况下迭代日期列表?

尝试在 C# 中迭代​​ IEnumerable<int> 时,指定的强制转换无效

c和c++中,对结构体进行强制类型转换!

java中将一个double类型的数强制转换为long 型是四舍五入吗?

java中将一个double类型的数强制转换为long 型是四舍五入吗?