【问题标题】:Iterate NSSet and cast to type in one step迭代 NSSet 并强制转换为一步到位
【发布时间】: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:这确实是一个好点!

标签: swift


【解决方案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://stackoverflow.com/a/35558210/2227743

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2014-01-25
    • 2011-01-09
    相关资源
    最近更新 更多