我有一个由10,000个结构组成的Swift数组:
struct Book {
var id: Int?
var name: String?
var pages: Int?
var words: Int?
}
var firstArray: [Book] = [] // contains 10,000 elements
还有第二个Swift类型为Int的Swift数组,其中包含5,000个元素:
var secondArray: [Int] = [] // contains 5,000 elements
我想通过删除firstArray中未包含id字段(Book.id)的所有元素来过滤firstArray。
知道Book.id对于firstArray中的每个元素都是唯一的,而且在序列中(从小到大)都是唯一的。例如。 1、2、3、6、8、10、14、15、16、40、50、51等(可能会跳过一些数字)
secondArray也是唯一的,并且按顺序(从小到大)
在Swift 4中筛选firstArray的最快方法是什么?
知道数组是一个序列时,随着处理数组的进行,过滤应该变得更快?这意味着如果我们在firstArray中途,我们将只遍历firstArray的一半以在secondArray中搜索匹配项。与secondArray相同,因为每次找到匹配项时数组都会变小。这一切有意义吗?
希望外面有人知道该怎么做。我已经在Android(Kotlin)上看到了此功能,但是如何在Swift中做到这一点?
我认为在Kotlin中就是这样:
firstArray?.let { dataFirstArray ->
secondArray?.let {
firstArray = ArrayList(dataFirstArray.asSequence().filter { dataSecondArray -> dataSecondArray in it }.toList())
}
}
答案 0 :(得分:1)
如果id
始终存在,请不要将其设为可选。
struct Book {
var id: Int
var name: String?
var pages: Int?
var words: Int?
}
最简单的过滤方法是一行:
func filter1(firstArray:[Book],secondArray:[Int]) -> [Book]
{
return firstArray.filter{secondArray.contains($0.id)}
}
我还尝试利用以下事实对数组进行排序:
func filter2(firstArray:[Book],secondArray:[Int]) -> [Book]
{
var j = 0;
return firstArray.filter{
while(j < secondArray.count && secondArray[j] < $0.id)
{
j += 1
}
if(j < secondArray.count && $0.id == secondArray[j])
{
j += 1
return true
}
return false
}
}
如评论所建议,我还尝试使用Set
:
func filter3(firstSet:Set<Book>,secondSet:Set<Int>) -> Set<Book>
{
return firstSet.filter{secondSet.contains($0.id)}
}
使用以下代码进行了测试:
var firstArray: [Book] = (0..<10000).map{Book(id: $0, name: nil, pages: nil, words: nil)}.filter {_ in Int.random(in: 0...1) == 0}
var secondArray: [Int] = (0..<10000).filter{_ in Int.random(in: 0...1) == 0}
var timestamp = Date().timeIntervalSince1970
let result1 = filter1(firstArray: firstArray, secondArray: secondArray)
print(Date().timeIntervalSince1970 - timestamp)
timestamp = Date().timeIntervalSince1970
let result2 = filter2(firstArray: firstArray, secondArray: secondArray)
print(Date().timeIntervalSince1970 - timestamp)
timestamp = Date().timeIntervalSince1970
let result3 = filter3(firstArray: firstArray, secondSet: Set(secondArray))
print(Date().timeIntervalSince1970 - timestamp)
测试结果:
2.687404155731201
0.0014042854309082031
0.002758026123046875
希望获得帮助