我有一个数组作为数字列表。在另一个较小的数组中,我保存了一些数字(顺序不同),我想使用第二个数组中的值过滤我的第一个数组。
我的数组:
let allNumbers = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
let someNumbers = [100, 90, 120, 200] // unordered
当我使用filter
方法或遍历第一个数组的值时,我可以得到正确的值,但是元素的顺序与第二个数组不同,而第一个数组自然。
方法1: filter
方法,丢失订单
let filtered = allNumbers.filter { someNumbers.contains($0) } // Runs 17 times
print(filtered) // "[90, 100, 120, 200]" (wrong order)
方法2:遍历第一个数组,丢失顺序
var filteredWithLoop: [Int] = []
for number in allNumbers { // Runs 16 Times
if someNumbers.contains(number) {
filteredWithLoop.append(number)
}
}
print(filteredWithLoop) // "[90, 100, 120, 200]" (wrong order)
Hack:我可以通过遍历第二个数组时过滤第一个数组来解决此问题,如下所示:
var filteredUglyWay: [Int] = []
for number in someNumbers {
if let alone = (allNumbers.filter { $0 == number }).first { // Runs 4 * 16 Times
filteredUglyWay.append(alone)
}
}
print(filteredUglyWay) // "[100, 90, 120, 200]" (correct order)
但这对我来说更像是一种破解,而不是一种解决方案,特别是考虑到循环式filter方法是在循环中调用的。
有更好的方法吗?还是这应该是这样?
重要说明:实际上,第一个数组是使情况更易于理解的表示。在我的实际实现中,第一个数组包含一些对象,第二个数组只是某些对象的ID列表(例如用户的收藏夹),因此,每次获取全部数据时,我都会尝试根据此过滤喜欢的对象ID列表。
答案 0 :(得分:1)
可能的解决方案: 过滤,然后排序。
let filtered = allNumbers.filtered({ someNumbers.contains($0) })
let filteredAndSorted = filtered.sorted(by: { someNumbers.index(of: $0)! < someNumbers.index(of: $1)! })
请注意,由于filtered
仅由someNumbers
中的数据组成,因此前部展开不会造成崩溃。
答案 1 :(得分:0)
为什么不尝试更新方法2
方法2已更新:遍历第二个数组
var filteredWithLoop: [Int] = []
for number in someNumbers { // Runs 4 Times
if allNumbers.contains(number) {
filteredWithLoop.append(number)
} // IF OBJECT IS NOT THERE IN FIRST ARRAY IT WILL BE AUTOMATICALLY DISCARDED
}
print(filteredWithLoop) // "[100, 90, 120, 200]" (proper order)