使用以下代码,您可以展示如何使用Swift CollectionType .filter .indexOf .map实例方法在命名元组数组中查找值/值?
文档here还不够。
import UIKit
class Foo {
private var mData: String
init(data: String) { mData = data }
func printData() { print(mData) }
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var myList = [(code:Int64, list: [Foo])]()
let fooListA = [Foo(data: "A0"), Foo(data: "A1"), Foo(data: "A2")]
let fooListB = [Foo(data: "B0"), Foo(data: "B1"), Foo(data: "B2")]
let fooListC = [Foo(data: "C0"), Foo(data: "C1"), Foo(data: "C2")]
let fooListD = [Foo(data: "D0"), Foo(data: "D1"), Foo(data: "D2")]
myList.append((code: 10, list: fooListA))
myList.append((code: 20, list: fooListB))
myList.append((code: 30, list: fooListC))
myList.append((code: 40, list: fooListD))
// following lines cause errors
let foundItem: (code:Int64, list:[Foo]) = myList.filter { (Self.Generator.Element) -> Bool in
if item.code = 20 {return true}
}
foundItem.list[1].printData() // prints 'B1'
let foundItemIdx = myList.indexOf { (Self.Generator.Element) -> Bool in
if item.code = 20 { return true}
}
print(foundItemIdx) // prints '1'
// extra credit how does map work???
}
}
答案 0 :(得分:5)
好的,有一些问题,让我们一步一步地完成它们:
filter
返回一个潜在的对象集合 - 仍然是一个集合。因此,您无法将结果分配给(code:Int64, list:[Foo])
但[(code:Int64, list:[Foo])]
类型的内容。或者你一起省略显式类型。
(Self.Generator.Element)
是闭包中第一个参数的泛型类型。再一次,你不必担心它的类型,只需写下参数的名称 - > item
:
let foundItem = myList.filter { item -> Bool in
过滤器中的内部代码并不总是返回值 - 只有在满足条件时才会返回 - 您应该始终返回一些内容:
if item.code == 20 {return true}; return false
这些陈述可以简化为
let foundItem = myList.filter { $0.code == 20 }
在我开始写的第一个语句之后,你不能得到一个项目,而是返回一个列表。因此,您必须有权访问该数组中特定索引处的元素:
foundItem[0].list[1].printData() // prints 'B1'
或者再次稍微更具功能性:
foundItem.forEach { $0.list[1].printData() }
或者,如果您只对第一个发现感兴趣,可以写:
let foundItem = myList.filter { $0.code == 20 }.first
if let found = foundItem {
found.list[1].printData() // prints 'B1'
}
上面的所有内容(除了收集内容)对于第二个“块”仍然是正确的:
let foundItemIdx = myList.indexOf { $0.code == 20 }
关于map:map
允许你对列表中的每个元素执行一个操作,返回一个列表,其中包含列表中的操作结果而不是原始元素:
let map2 = myList.map { $0.code / 10 }
let map3 = myList.map { $0.list[0].mData }
print(map2) // [1, 2, 3, 4]
print(map3) // ["A0", "B0", "C0", "D0"]
答案 1 :(得分:1)
感谢luk2302让这个易于理解。对于那些寻找快速展示如何使用这些方法的例子的人来说,用Luk2302的解决方案重写了代码:
var myList = [(code:Int64, list: [Foo])]()
let fooListA = [Foo(data: "A0"), Foo(data: "A1"), Foo(data: "A2")]
let fooListB = [Foo(data: "B0"), Foo(data: "B1"), Foo(data: "B2")]
let fooListC = [Foo(data: "C0"), Foo(data: "C1"), Foo(data: "C2")]
let fooListD = [Foo(data: "D0"), Foo(data: "D1"), Foo(data: "D2")]
myList.append((code: 10, list: fooListA))
myList.append((code: 20, list: fooListB))
myList.append((code: 30, list: fooListC))
myList.append((code: 40, list: fooListD))
// .filter - long way
let foundItem = myList.filter { item -> Bool in
if item.code == 20 {
return true
} else {
return false
}
}
if let foundFirst = foundItem.first {
foundFirst.list[1].printData() // prints 'B1'
}
// .filter - short way
if let foundItem = (myList.filter { $0.code == 20 }).first {
foundItem.list[1].printData() // prints 'B1'
}
// .indexOf - long way
let foundItemIdx = myList.indexOf { item -> Bool in
if item.code == 20 {
return true
} else {
return false
}
}
if let foundItemIndexUnwrapped = foundItemIdx {
print(foundItemIndexUnwrapped) // prints '1'
}
// .indexOf - short way
if let foundItemIdxShortWay = (myList.indexOf { $0.code == 20 }) {
print(foundItemIdxShortWay) // prints '1'
}
// map examples
let map2 = myList.map { $0.code / 10 }
let map3 = myList.map { $0.list[0].mData }
print(map2) // [1, 2, 3, 4]
print(map3) // ["A0", "B0", "C0", "D0"]