使用map
,filter
,reduce
和朋友,必须有更具表现力的方式。
背景:
categories
属性为[Category]?
,其中每个元素都具有videos
类型的[Video]
属性。
我正在尝试找到video
的索引路径。
var indexPath: NSIndexPath?
for var i = 0; i < categories?.count ; ++i {
for var j = 0; j < categories?[i].videos.count ; ++j {
if categories?[i].videos[j] == video {
indexPath = NSIndexPath(forRow: j, inSection: i)
}
}
}
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([ indexPath ], withRowAnimation: UITableViewRowAnimation.Automatic)
}
答案 0 :(得分:3)
可能的解决方案(用 Swift 2 编写):
let indexPaths = categories?.enumerate().flatMap() { (section, aCategory) in
aCategory.videos.enumerate().filter() { (_, aVideo) in
aVideo == video
}.map { (row, _) in
NSIndexPath(forRow: row, inSection: section)
}
} ?? []
indexPaths
是所有匹配索引路径(或空数组)的数组。如果您不需要/喜欢,请使用
let indexPath = categories?.enumerate().flatMap() { (section, aCategory) in
aCategory.videos.enumerate().filter() { (_, aVideo) in
aVideo == video
}.map { (row, _) in
NSIndexPath(forRow: row, inSection: section)
}
}.first
而是,这是一个可选的索引路径。
categories?.enumerate()
是一系列(section, aCategory)
对。对于每个类别,aCategory.videos.enumerate()
是一个
(row, aVideo)
对的序列。该序列被过滤
根据搜索项,映射过滤后的对
到索引路径。
因此传递给flatMap()
的转换结果是一个数组
匹配项的索引路径,每个类别一个数组。
flatMap()
将这些连接到一个数组。
在 Swift 1.2 中,这将是
let indexPaths = flatMap(enumerate(categories ?? [])) { (section, aCategory) in
filter(enumerate(aCategory.videos)) { (_, aVideo) in
aVideo == video
}.map { (row, _) in
NSIndexPath(forRow: row, inSection: section)
}
}
答案 1 :(得分:1)
这不是最实用的,也不是最简洁的,但它对我来说似乎很可读。假设要找到的视频是唯一的。
var location: NSIndexPath? = nil
for (section, category) in enumerate(categories ?? []) {
if let row = find(category.videos, video) {
location = NSIndexPath(forRow: row, inSection: section)
break
}
}
答案 2 :(得分:0)
如果您很少这样做,请创建一个返回索引路径和视频元组的生成器,然后根据您需要的视频过滤视频
如果你创建一个枚举生成器,它主要将循环移动到它自己的对象中。 categoryIndex和videoIndex成为生成器中的变量,接下来基本上执行for循环语句的第2 /第3个子句
目前,您正在有效地处理视频索引路径字典。
如果您经常进行此查找并很少更改集合中的数据,维护双向字典(视频 - &gt; IP)和(IP-&gt;视频)可能会更快,然后它就会#39 ;快速查找项目的操作。生成器是一种创建数据结构的方法,但老实说,如果性能成为一个问题,你必须涉及一个分析器