2015-11-03 52 views
11

假设我有一个AnyObject的数组。按类型过滤Swift [AnyObject]数组

let grabBag: [AnyObject] = [ "Tom", 4, "Dick", NSObject(), "Harry" ] 

,我想它转换的Strings阵列,只抽出,它们事实上Strings这些元素。我期望这个工作:

let strings = grabBag.filter{ $0 is String } as! [String]  // 1 

但它给出了错误'Bool' is not convertible to 'String'。然而,这个工程:

let definitelyStrings = grabBag.filter{ $0 is String }   // 2 
let strings = definitelyStrings as! [String]     // 

为什么2工作时1不?是否有比更简单(比2)提取和投射[AnyObject]的元素的方法?

+0

在示例2中,您不需要第二行:'let strings = grabBag.filter {$ 0 is String}'就足够了。没有强制类型转换。用''字符串'[String]'证明它返回真正的 – vadian

+2

@vadian'let strings = grabBag.filter {$ 0 is String}'返回具有OP的'grabBag'数组而不是'[String]'的'[AnyObject]'。 – Moritz

+0

@EricD:但是你可以通过'[AnyObject]'' – vadian

回答

15

它更好使用flatMap作为一个不错的单行:

​​

现在strings[String]类型。

6

这是flatMap是:

let strings = grabBag.flatMap{ $0 as? String } 

这需要关闭返回一个可选的;如果可选非零,则将其添加到结果中。

请注意,这不匹配的 flatMap从其他语言的意思,甚至不匹配的斯威夫特 flatMap其他含义。一个更好的名字本来 mapOptionalmapSome,但它是一种还直观,即使不一致,它“映射到可选项,然后展平所有nils。” Rob Mayoff指出,如果可选项是SequenceTypes,他们可能应该是这样,这将是一个明智的名称。)

+1

斯卡拉的'flatMap'与'Option'一起工作,Swift的'flatMap'与'Optional'一起工作。但是Scala可以“免费”获取它,因为Scala的'Option'是一个完整的traversable-collection类型(包含0或1个元素)。可悲的是,Swift的'Optional'不符合'SequenceType'。 –

+0

@robmayoff我误解了Scala的签名。它是'flatMap [B](f:(A)⇒GenTraversableOnce[B]):List [B]'。我认为它是'flatMap [B](f:(A)⇒列表[列表[B]]):列表[B]'。好;我会买那个。 –

3

我想说测试1失败显然是一个编译器错误。事实上,它崩溃的REPL:

Welcome to Apple Swift version 2.0 (700.1.100.2 700.1.74). Type :help for assistance. 
    1> import Foundation 
    2> let grabBag: [AnyObject] = [ "Tom", 4, "Dick", NSObject(), "Harry" ] 
grabBag: [AnyObject] = 5 values { 
    [0] = "Tom" 
    [1] = Int64(4) 
    [2] = "Dick" 
    [3] = { 
    isa = NSObject 
    } 
    [4] = "Harry" 
} 
    3> let strings = grabBag.filter { $0 is String } as! String 
strings: String = { 
    _core = { 
    _baseAddress = 
    _countAndFlags = 
    _owner = <extracting data from value failed> 

    } 
} 
Execution interrupted. Enter Swift code to recover and continue. 
Enter LLDB commands to investigate (type :help for assistance.) 
4> :bt 
* thread #1: tid = 0x501bac, 0x00000001005c41f4 $__lldb_expr12`main + 420 at repl.swift:3, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 
    * frame #0: 0x00000001005c41f4 $__lldb_expr12`main + 420 at repl.swift:3 
    frame #1: 0x0000000100001420 repl_swift`_mh_execute_header + 5152 
    frame #2: 0x00007fff8dd725c9 libdyld.dylib`start + 1 
    frame #3: 0x00007fff8dd725c9 libdyld.dylib`start + 1 

无论如何,罗布纳皮尔还回答了,grabBag.flatMap { $0 as? String }较短,也许更简单。

相关问题