Swift:获取由某个属性过滤的对象数组的索引

Posted

技术标签:

【中文标题】Swift:获取由某个属性过滤的对象数组的索引【英文标题】:Swift: Get indices of an array of objects filtered by a certain property 【发布时间】:2020-05-21 18:27:48 【问题描述】:

我有一个自定义对象数组,将 ID 值作为属性。现在我有另一个选定对象数组(由 ID 选择)。如何通过筛选选定的 ID(第二个数组)来获取第一个数组的索引?

我想避免循环并考虑使用compactMap 或类似的解决方案。

struct MyObject 
    var ID: Int
    var name: String


let myObjects = [
    MyObject(ID: 3, name: "AAAA"),
    MyObject(ID: 5, name: "BBBB"),
    MyObject(ID: 12, name: "CCCC"),
    MyObject(ID: 15, name: "DDDD"),
    MyObject(ID: 20, name: "EEEE"),
    MyObject(ID: 21, name: "GGGG"),
    MyObject(ID: 22, name: "HHHH"),
    MyObject(ID: 23, name: "IIII"),
]
let selectedIds = [5, 20, 23]

// How to get an array of indices for selectedIds
// Expected result [1, 4, 7]

【问题讨论】:

【参考方案1】:
myObjects.enumerated()   // Pair-up elements and their offsets
    .filter  selectedIds.contains($0.element.ID)   // Get the ones you want
    .map  $0.offset   // Extract the offsets

【讨论】:

这比@vadian myObjects.indices.filterselectedIds.contains(myObjects[$0].ID)的回答快还是慢 如果它在您的特定情况下很重要,那么对您的特定情况进行基准测试。正确地进行基准测试非常棘手,您的情况的微小差异可能会显着改变性能。如果这么小的微优化对您的情况很重要,那么有更多的性能方法可以做到这一点,但代价是代码复杂性,以及每次更改编译器时重新测试性能的成本。 @Pauli vadian 方法的优势在于它也适用于集合切片。一个枚举偏移量它与一个集合索引不同 没错;您必须将其替换为 zip(myObjects.indices, myObjects) 才能在非数组中获得相同的基于索引的行为。 Vadian 的方法也适用于任意集合,这很好。 @RobNapier 感谢您提供更多详细信息。我会接受 vadian 的方法,因为它似乎更完整一些,但是因为它工作正常,所以要支持你的方法。谢谢【参考方案2】:

您可以过滤indices

let selectedIndices = myObjects.indices.filterselectedIds.contains(myObjects[$0].ID)

【讨论】:

以上是关于Swift:获取由某个属性过滤的对象数组的索引的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 3.0 中,没有在数组中的索引处获取对象的键值语法

JS 过滤数组里对象的某个属性

如何枚举swift 4中的zip数组以获取每个对象的索引

Swift - 如何获取数组过滤项的索引

用于多重过滤 Swift 的布尔语句

swift 从对象数组中获取属性值数组