Reputation: 2990
I understand how to write a for loop using swift syntax (using .enumerate() and .revers()), however how would I re-write (in swift) the following javascript version of for loop, considering I have multiple conditions to adhere to:
for(var j = 10; j >= 0 && array[j] > value; j--) {
array[j + 1] = array[j];
}
Upvotes: 0
Views: 692
Reputation: 80901
For the sake of completion (I would personally prefer to use a for
loop with a check for an early break
, as others have already suggested) – in Swift 3.1 you could use Sequence
's prefix(while:)
method in order to get the suffix of the array's indices where the elements meet a given predicate.
var array = [2, 3, 6, 19, 20, 45, 100, 125, 7, 9, 21, 22]
let value = 6
for i in array.indices // the array's indices.
.dropLast() // exclude the last index as we'll be accessing index + 1 in the loop.
.reversed() // reversed so we can get the suffix that meets the predicate.
.prefix(while: {array[$0] > value}) // the subsequence from the start of the
{ // collection where elements meet the predicate.
array[i + 1] = array[i]
}
print(array) // [2, 3, 6, 19, 19, 20, 45, 100, 125, 7, 9, 21]
This is assuming that you're looking to begin iterating at the penultimate index of the array. If you want to start at a particular index, you can say:
for i in (0...10).reversed().prefix(while: {array[$0] > value}) {
array[i + 1] = array[i]
}
This will start at the index 10 and iterate down to 0, giving you the same behaviour to the code in your question.
It's worth noting that both of the above variants will first iterate through the reversed indices (until the predicate isn't met), and then through the array's elements. Although, in Swift 3.1, there is a version of prefix(while:)
which operates on a lazy sequence – which would allow for just a single iteration through the elements until the predicate isn't met.
Until Swift 3.1, you can use the below extension to get prefix(while:)
on a Collection
:
extension Collection {
func prefix(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSequence {
var index = startIndex
while try index < endIndex && predicate(self[index]) {
formIndex(after: &index)
}
return self[startIndex..<index]
}
}
Upvotes: 0
Reputation: 285150
I'm not sure that produces exactly the same result, but this is one of the approaches in Swift 3
for j in stride(from:10, through:0, by: -1) {
if array[j] <= value { break }
array[j + 1] = array[j]
}
Upvotes: 2
Reputation: 59526
What about this?
for j in (0...10).reversed() {
guard array[j] > value else { break }
array[j + 1] = array[j]
}
Upvotes: 2