Swift数组:在使用另一个过滤数组时保持顺序

时间:2018-07-13 12:25:27

标签: ios arrays swift loops filtering

我有一个数组作为数字列表。在另一个较小的数组中,我保存了一些数字(顺序不同),我想使用第二个数组中的值过滤我的第一个数组。

我的数组:

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列表。

2 个答案:

答案 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)