Swift - How to get indexes of filtered items of array

后端 未结 9 1138
旧巷少年郎
旧巷少年郎 2020-12-05 18:20
let items: [String] = [\"A\", \"B\", \"A\", \"C\", \"A\", \"D\"]

items.whatFunction(\"A\") // -> [0, 2, 4]
items.whatFunction(\"B\") // -> [1]
相关标签:
9条回答
  • 2020-12-05 18:30

    You can use that below code:

    var firstArray = ["k","d","r","r","p","k","b","p","k","k"]
    var secondArray = ["k","d","r","s","d","r","b","c"]
    
    let filterArray = firstArray.filter { secondArray.contains($0) }
    let filterArray1 = firstArray.filter { !secondArray.contains($0) }
    let filterIndex = firstArray.enumerated().filter { $0.element == "k" }.map { $0.offset }
    print(filterArray) --> // ["k", "d", "r", "r", "k", "b", "k", "k"]
    print(filterArray1) --> // ["p", "p"]
    print(filterIndex) --> // [0, 5, 8, 9]
    
    0 讨论(0)
  • 2020-12-05 18:33

    For example finding the indices of p_last values that are in inds1 array: (swift 4+)

    let p_last = [51,42]
    let inds1 = [1,3,51,42,4]
    let idx1 = Array(inds1.filter{ p_last.contains($0) }.indices)
    

    idx1 = [0,1]

    0 讨论(0)
  • 2020-12-05 18:34

    You can create your own extension for arrays.

    extension Array where Element: Equatable {
        func indexes(of element: Element) -> [Int] {
            return self.enumerated().filter({ element == $0.element }).map({ $0.offset })
        }
    }
    

    You can simply call it like this

    items.indexes(of: "A") // [0, 2, 4]
    items.indexes(of: "B") // [1]
    
    0 讨论(0)
  • 2020-12-05 18:34

    In Swift 3 and Swift 4 you can do that:

    let items: [String] = ["A", "B", "A", "C", "A", "D"]
    
    extension Array where Element: Equatable {
    
        func indexes(of item: Element) -> [Int]  {
            return enumerated().compactMap { $0.element == item ? $0.offset : nil }
        }
    }
    
    items.indexes(of: "A")
    

    I hope my answer was helpful

    0 讨论(0)
  • 2020-12-05 18:35

    You can filter the indices of the array directly, it avoids the extra mapping.

    let items = ["A", "B", "A", "C", "A", "D"]
    let filteredIndices = items.indices.filter {items[$0] == "A"}
    

    or as Array extension:

    extension Array where Element: Equatable {
    
        func whatFunction(_ value :  Element) -> [Int] {
            return self.indices.filter {self[$0] == value}
        }
    
    }
    
    items.whatFunction("A") // -> [0, 2, 4]
    items.whatFunction("B") // -> [1]
    

    or still more generic

    extension Collection where Element: Equatable {
    
        func whatFunction(_ value :  Element) -> [Index] {
            return self.indices.filter {self[$0] == value}
        }
    
    }
    
    0 讨论(0)
  • 2020-12-05 18:37

    You can achieve this by chain of:

    1. enumerated() - add indexes;
    2. filter() out unnecessary items;
    3. map() our indexes.

    Example (works in Swift 3 - Swift 4.x):

    let items: [String] = ["A", "B", "A", "C", "A", "D"]  
    print(items.enumerated().filter({ $0.element == "A" }).map({ $0.offset })) // -> [0, 2, 4]
    

    Another way is using flatMap, which allows you to check the element and return index if needed in one closure.

    Example (works in Swift 3 - Swift 4.0):

    print(items.enumerated().flatMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
    

    But since Swift 4.1 flatMap that can return non-nil objects become deprecated and instead you should use compactMap.

    Example (works since Swift 4.1):

    print(items.enumerated().compactMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
    

    And the cleanest and the most memory-cheap way is to iterate through array indices and check if element of array at current index equals to required element.

    Example (works in Swift 3 - Swift 4.x):

    print(items.indices.filter({ items[$0] == "A" })) // -> [0, 2, 4]
    
    0 讨论(0)
提交回复
热议问题