我创建了两个数组,并且必须根据第二个数组从第一个数组中获取数据。
struct UserData {
let name: String
let data: Int
}
let sourceArray: [UserData] = [UserData(name: "a", data: 1),
UserData(name: "b", data: 2),
UserData(name: "c", data: 3),
UserData(name: "d", data: 4),
UserData(name: "d", data: 5)]
let filterArray = [2,3,2,5]
我想要的结果数组是:
[UserData(name: "b", data: 2),
UserData(name: "c", data: 3),
UserData(name: "b", data: 2),
UserData(name: "d", data: 5)]
因此它可以根据array2中的数据具有重复的数据。
现在我尝试使用高阶函数filter
:
let resultArray = sourceArray.filter { (userData) -> Bool in
return filterArray.contains(userData.data)
}
但是这将删除重复的数据,并且输出为:
[UserData(name: "b", data: 2),
UserData(name: "c", data: 3),
UserData(name: "d", data: 5)]
我尝试的一种方法是使用for循环:
var resultArray = [UserData]()
for i in filterArray {
resultArray.append(sourceArray.filter({ $0.data == i }).first!)
}
这将提供所需的输出,但是如果有更好的方法,请提出建议。
您可以使用first(where:)
解决此问题,以搜索array1
:
let result = filterArray.map { desiredDataValue in
sourceArray.first(where: { $0.data == desiredDataValue })
}
result.forEach { print($0) }
但是,如果您经常执行此操作,则构建的数据结构可以通过“ data”值进行快速查找,这样可能会加快速度。您应该自己比较性能,看看是否足够/频繁地执行此操作,这样才值得:
let dictsByData = Dictionary(uniqueKeysWithValues:
sourceArray
.lazy
.map { dict in
(key: dict.data, value: dict)
}
)
let result = filterArray.map { desiredDataValue in dictsByData[desiredDataValue]! }
result.forEach { print($0) }
在进一步研究之后,并在此博客的帮助下,很好:
我尝试这样做:
let resultArray = filterArray.compactMap { (int) -> UserData? in
var data: UserData?
if sourceArray.contains(where: { (userData) -> Bool in
if userData.data == int {
data = userData
}
return userData.data == int
}) {
return data
}
return nil
}
并且在操场上,我检查了执行代码的数量:
并且与“ for”循环相比,计数似乎更少。