Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:第二次出现在indexOf中_Swift_Swift3.0.2 - Fatal编程技术网

Swift:第二次出现在indexOf中

Swift:第二次出现在indexOf中,swift,swift3.0.2,Swift,Swift3.0.2,要查找第一个5,请使用: let numbers = [1,3,4,5,5,9,0,1] 如何找到第二次发生的情况?我认为您不能使用indexOf进行查找。相反,您必须使用for循环。简写版: numbers.indexOf(5) 列表项 您可以在剩余的数组切片上对元素的索引执行另一次搜索,如下所示: 编辑/更新:Swift 5.2或更高版本 let numbers = [1,3,4,5,5,9,0,1] var indexes = [Int]() numbers.enumerate()

要查找第一个
5
,请使用:

let numbers = [1,3,4,5,5,9,0,1]

如何找到第二次发生的情况?

我认为您不能使用
indexOf
进行查找。相反,您必须使用
for循环
。简写版:

numbers.indexOf(5)
  • 列表项
您可以在剩余的数组切片上对元素的索引执行另一次搜索,如下所示:

编辑/更新:Swift 5.2或更高版本

let numbers = [1,3,4,5,5,9,0,1]
var indexes = [Int]()
numbers.enumerate().forEach { if $0.element == 5 { indexes += [$0.index] } }

print(indexes) // [3, 4]

测试:

extension Collection {
    /// Returns the second index in which an element of the collection satisfies the given predicate.
    func secondIndex(where predicate: (Element) throws -> Bool) rethrows -> Index? {
        guard let index = try firstIndex(where: predicate) else { return nil }
        return try self[self.index(after: index)...].firstIndex(where: predicate)
    }
}

下面是
Array
的一个通用扩展,用于查找任何数组中的第n个元素:

let numbers = [1,3,4,5,5,9,0,1]
if let index = numbers.secondIndex(of: 5) {
    print(index)    // "4\n"
} else {
    print("not found")
}    
if let index = numbers.secondIndex(where: { $0.isMultiple(of: 3) }) {
    print(index)    // "5\n"
} else {
    print("not found")
}

找到第一个匹配项后,可以在数组的其余部分上使用
indexOf
来定位第二个匹配项:

extension Array where Element: Equatable {
    // returns nil if there is no nth occurence
    // or the index of the nth occurence if there is
    func findNthIndexOf(n: Int, thing: Element) -> Int? {
        guard n > 0 else { return nil }
        var count = 0
        for (index, item) in enumerate() where item == thing {
            count += 1
            if count == n {
                return index
            }
        }
        return nil
    }
}

let numbers = [1,3,4,5,5,9,0]

numbers.findNthIndexOf(2, thing: 5) // returns 4
let number=[1,3,4,5,5,9,0,1]
如果设firstFive=numbers.indexOf(5){//3

让secondFive=数字[firstFive+1..编辑:根据@davecom的评论,我在答案底部包含了一个类似但稍微复杂的解决方案

我在这里看到了一些很好的解决方案,特别是考虑到Swift相对较新的语言的局限性。也有一种非常简洁的方法可以做到这一点,但请注意……它相当快速和肮脏。可能不是完美的解决方案,但它相当快速。而且非常通用(不要吹嘘)

使用此扩展,您可以访问第二个索引,如下所示:

extension Array where Element: Equatable {
    func indexes(search: Element) -> [Int] {
        return enumerate().reduce([Int]()) { $1.1 == search ? $0 + [$1.0] : $0 }
    }
}
你就完了!

基本上,该方法是这样工作的:
enumerate()
将数组映射到元组,包括每个元素与元素本身的索引。在本例中,
[1,3,4,5,5,9,0,1]。enumerate()
返回有关JS中函数使用的类型
enumerate序列的集合(请记住,传入的非块参数的位置是在JS中的块之后输入的,而不是在这里看到的块之前)

谢谢你的阅读

let randomNumbers = (1...10000).map{_ in Int(rand() % 100)}

let indexes = randomNumbers.indexes(93) // count -> 100 (in my first run)
let index1 = indexes[1] // 238
// executed in 29.6603130102158 sec

let index2 = randomNumbers.nIndex(93, n: 2) // 238
// executed in 3.82625496387482 sec
请注意,不要对这个相对简单的解决方案长篇大论,但是如果上面显示的
index
方法的语法有点太快太脏,您可以在方法体中尝试类似的方法,在方法体中,闭包的参数被扩展以更清晰一些:

let numbers = [1, 3, 4, 5, 5, 9, 0, 1]
let indexesOf5 = numbers.indexes(5) // [3, 4]

indexesOf5[1] // 4
编辑:这里有另一个选项,允许实施者在索引处扫描特定的“索引”(例如,第二次出现5),以获得更有效的解决方案

return enumerate().reduce([Int]()) { memo, element in
    element.1 == search ? memo + [element.0] : memo
}
可以看出,这种新方法在处理(非常)大的数据集时速度要快得多;但它有点麻烦和混乱,因此根据您的应用程序,您可能更喜欢更简单的解决方案,或者完全不同的解决方案


(再次)感谢阅读。

这太难了,因为我只想找到第二个匹配项。我的数组很大。此解决方案的问题与@Eendje的问题相同-如果您只想要第二个匹配项,您将仍然搜索整个数组,这可能是一个巨大的性能陷阱。换句话说在最坏情况、平均情况和最佳情况下都是O(n),而在最佳情况下(如果你在寻找第一个元素,则是O(1),如果你在寻找第二个元素,则是O(2),只有O(n)在最坏的情况下。@davecom这是一个很好的观点,但在某些情况下,这并不是一个大问题,而且使用少量数据对性能的影响可以忽略不计。我将更新解决方案,使其包含一个选项,以更有效地查找特定的“索引处的索引”。
let randomNumbers = (1...10000).map{_ in Int(rand() % 100)}

let indexes = randomNumbers.indexes(93) // count -> 100 (in my first run)
let index1 = indexes[1] // 238
// executed in 29.6603130102158 sec

let index2 = randomNumbers.nIndex(93, n: 2) // 238
// executed in 3.82625496387482 sec
extension Array where Element: Equatable {
    func nIndex(search: Element, n: Int) -> Int? {
        let info = enumerate().reduce((count: 0, index: 0), combine: { memo, element in
            memo.count < n && element.1 == search ? (count: memo.count + 1, index: element.0) : memo
        })
        return info.count == n ? info.index : nil
    }
}

[1, 3, 4, 5, 5, 9, 0, 1].nIndex(5, n: 2) // 4
[1, 3, 4, 5, 5, 9, 0, 1].nIndex(5, n: 3) // nil
let randomNumbers = (1...10000).map{_ in Int(rand() % 100)}

let indexes = randomNumbers.indexes(93) // count -> 100 (in my first run)
let index1 = indexes[1] // 238
// executed in 29.6603130102158 sec

let index2 = randomNumbers.nIndex(93, n: 2) // 238
// executed in 3.82625496387482 sec
extension Collection where Element: Equatable {
    func nth(occurance: Int, of element: Element) -> Index? {
        var level : Int = occurance
        var position = self.startIndex
        while let index = self[position...].index(of: element) {
            level -= 1
            guard level >= 0 else { return nil }
            guard level != 0 else { return index }
            position = self.index(after: index)
        }
        return nil
    }
}