|
2 | 2 | //
|
3 | 3 | // This source file is part of the Swift.org open source project
|
4 | 4 | //
|
5 |
| -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors |
| 5 | +// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors |
6 | 6 | // Licensed under Apache License v2.0 with Runtime Library Exception
|
7 | 7 | //
|
8 | 8 | // See https://swift.org/LICENSE.txt for license information
|
@@ -209,6 +209,74 @@ extension BidirectionalCollection where Element: Equatable {
|
209 | 209 | }
|
210 | 210 | }
|
211 | 211 |
|
| 212 | +//===----------------------------------------------------------------------===// |
| 213 | +// indices(where:) / indices(of:) |
| 214 | +//===----------------------------------------------------------------------===// |
| 215 | + |
| 216 | +#if !$Embedded |
| 217 | +extension Collection { |
| 218 | + /// Returns the indices of all the elements that match the given predicate. |
| 219 | + /// |
| 220 | + /// For example, you can use this method to find all the places that a |
| 221 | + /// vowel occurs in a string. |
| 222 | + /// |
| 223 | + /// let str = "Fresh cheese in a breeze" |
| 224 | + /// let vowels: Set<Character> = ["a", "e", "i", "o", "u"] |
| 225 | + /// let allTheVowels = str.indices(where: { vowels.contains($0) }) |
| 226 | + /// // str[allTheVowels].count == 9 |
| 227 | + /// |
| 228 | + /// - Parameter predicate: A closure that takes an element as its argument |
| 229 | + /// and returns a Boolean value that indicates whether the passed element |
| 230 | + /// represents a match. |
| 231 | + /// - Returns: A set of the indices of the elements for which `predicate` |
| 232 | + /// returns `true`. |
| 233 | + /// |
| 234 | + /// - Complexity: O(*n*), where *n* is the length of the collection. |
| 235 | + @available(SwiftStdlib 5.11, *) |
| 236 | + @inlinable |
| 237 | + public func indices( |
| 238 | + where predicate: (Element) throws -> Bool |
| 239 | + ) rethrows -> RangeSet<Index> { |
| 240 | + var result: [Range<Index>] = [] |
| 241 | + var end = startIndex |
| 242 | + while let begin = try self[end...].firstIndex(where: predicate) { |
| 243 | + end = try self[begin...].prefix(while: predicate).endIndex |
| 244 | + result.append(begin ..< end) |
| 245 | + |
| 246 | + guard end < self.endIndex else { |
| 247 | + break |
| 248 | + } |
| 249 | + self.formIndex(after: &end) |
| 250 | + } |
| 251 | + |
| 252 | + return RangeSet(_orderedRanges: result) |
| 253 | + } |
| 254 | +} |
| 255 | + |
| 256 | +extension Collection where Element: Equatable { |
| 257 | + /// Returns the indices of all the elements that are equal to the given |
| 258 | + /// element. |
| 259 | + /// |
| 260 | + /// For example, you can use this method to find all the places that a |
| 261 | + /// particular letter occurs in a string. |
| 262 | + /// |
| 263 | + /// let str = "Fresh cheese in a breeze" |
| 264 | + /// let allTheEs = str.indices(of: "e") |
| 265 | + /// // str[allTheEs].count == 7 |
| 266 | + /// |
| 267 | + /// - Parameter element: An element to look for in the collection. |
| 268 | + /// - Returns: A set of the indices of the elements that are equal to |
| 269 | + /// `element`. |
| 270 | + /// |
| 271 | + /// - Complexity: O(*n*), where *n* is the length of the collection. |
| 272 | + @available(SwiftStdlib 5.11, *) |
| 273 | + @inlinable |
| 274 | + public func indices(of element: Element) -> RangeSet<Index> { |
| 275 | + indices(where: { $0 == element }) |
| 276 | + } |
| 277 | +} |
| 278 | +#endif |
| 279 | + |
212 | 280 | //===----------------------------------------------------------------------===//
|
213 | 281 | // partition(by:)
|
214 | 282 | //===----------------------------------------------------------------------===//
|
|
0 commit comments