Swift fatal error: Can't form Range with end start
for in (0...row-1).reverse()
Swift can't read row-1...0
Can't form Range with end start
Your for has two problems:
- If
slashList.count
is 0 (becauseslashList
is empty), it would try to count from 1 to 0 adding 1 (which results in an infinite loop), that's why the compiler gives you the errorstart > end
. - if
slashList.count
is greater than 0 (slashList
is not empty), it would use an index which is out of bounds, because you count from 1 toslashList.count
, while the indexes go from 0 toslashList.count - 1
to check all indexes it should be:
for i in 0 ..< slashList.count {
// your code
}
to ignore the first element (index 0) do:
for i in 1 ..< slashList.count {
// your code
}
for your special case, it would seem better to me to do something like:
for element in slashList {
if !quotaList.contains(element+1)
{
slashList.removeObject(element)
}
}
You can use removeObject from this answer. If, for some reason, you also need the index, do:
for (index, element) in slashList.enumerate() {
// your code
}
Can't form Range with end start Check range before doing for loop?
If you just want to iterate over a collection, then use the for <element> in <collection>
syntax.
for element in arr {
// do something with element
}
If you also need access to the index of the element at each iteration, you can use enumerate()
. Because indices are zero based, the index will have the range 0..<arr.count
.
for (index, element) in arr.enumerate() {
// do something with index & element
// if you need the position of the element (1st, 2nd 3rd etc), then do index+1
let position = index+1
}
You can always add one to the index at each iteration in order to access the position (to get a range of 1..<arr.count+1
).
If none of these solve your problem, then you can use the range 0..<arr.count
to iterate over the indices of your array, or as @vacawama says, you could use the range 1..<arr.count+1
to iterate over the positions.
for index in 0..<arr.count {
// do something with index
}
for position in 1..<arr.count+1 {
// do something with position
}
0..<0
cannot crash for an empty array as 0..<0
is just an empty range, and 1..<arr.count+1
cannot crash for an empty array as 1..<1
is also an empty range.
Also see @vacawama's comment below about using stride
for safely doing more custom ranges. For example (Swift 2 syntax):
let startIndex = 4
for i in startIndex.stride(to: arr.count, by: 1) {
// i = 4, 5, 6, 7 .. arr.count-1
}
Swift 3 syntax:
for i in stride(from: 4, to: arr.count, by: 1) {
// i = 4, 5, 6, 7 .. arr.count-1
}
This is where startIndex
is the number to start the range at, arr.count
is the number that the range will stay below, and 1
is the stride length. If your array has less elements than the given starting index, then the loop will never be entered.
Can't form Range with upperBound lowerBound
You should first parse your date strings, which are UTC time, into date objects using DateFormatter or ISO8601DateFormatter and get the month and day representation from the resulting dates:
extension Formatter {
static let monthDay: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM.dd"
return dateFormatter
}()
}
extension Formatter {
static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return formatter
}()
}
Playground testing:
let dealStatus: [String: Any] = ["dateStart": "2019-08-21T14:54:03.285108Z",
"dateEnd" : "2019-09-20T06:15:03.285108Z"]
if let dateStart = dealStatus["dateStart"] as? String,
let dateEnd = dealStatus["dateEnd"] as? String,
let start = Formatter.iso8601.date(from: dateStart),
let end = Formatter.iso8601.date(from: dateEnd) { // ,
// let catTitle = ordersResponseArray[indexPath.row]["title"] as? String {
let startTime = Formatter.monthDay.string(from: start)
let endTime = Formatter.monthDay.string(from: end)
let startEndDates = "(" + startTime + " - " + endTime + ")"
print(startEndDates) // "(08.21 - 09.20)"
// cell.titleAndDatesLabel.text = catTitle + " " + startEndDates
}
A concise way to not execute a loop now that C-Style for loops are going to be removed from Swift 3?
To do this in a way that works for n < 2, you can use the stride
method.
let startIndex = 2
let endIndex = n
for i in stride(from: startIndex, through: endIndex, by: 1) {
memo.append(memo[i-1] + memo[i-2])
}
For- in loop dynamic closed range
[10-x]
denotes an array (with the single element 10-x
). You'll want "normal"
parentheses:
for z in 1 ... (10 - x) { ... }
or just
for z in 1 ... 10 - x { ... }
because ...
has a lower precedences than -
.
As you noticed, this does not work for x = 10
because ranges with end < start
are not allowed in Swift.
To execute a loop n
times you better use the range 0 ..< n
with the range operator that omits the upper value. This works for n = 0
as well:
for x in 1 ... 10 {
for y in 0 ..< x {
print(" ")
}
for z in 0 ..< 10 - x {
print("*")
}
println()
}
Related Topics
Swiftui MACos Xcode Style Toolbar
How to Create Custom Uimenucontroller with Only Custom Items Other Than Default
Switch That Checks Nsindexpath's Row and Section
Add Text Label and Button to Dynamic Tableview Cell Programmatically with Swift
Module File's Deployment Target Is iOS9.0 V9.0 with Xcode 7/Swift 2
How to Retrieve the Type of an Object in Swift
Sending Whatsapp Message to a Specific Contact Number (Swift Project)
Swift, Nsjsonserialization and Nserror
Change What Print(Object) Displays in Swift 2.0
Scenekit - Get Direction of Camera
Hide Tab Bar in View with Push
Local Swift Packages Stopped Working in Xcode 13
How to Make a Uiview Focusable Using the Focus Engine on Apple Tv
How to Get Class Name of Parent Viewcontroller in Swift
In Swiftui How to Set the Environment Variable of Editmode in an Xcodepreview