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 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
}
Swift fatal error: Can't form Range with end start
for in (0...row-1).reverse()
Swift can't read row-1...0
Why does range(start, end) not include end?
Because it's more common to call range(0, 10)
which returns [0,1,2,3,4,5,6,7,8,9]
which contains 10 elements which equals len(range(0, 10))
. Remember that programmers prefer 0-based indexing.
Also, consider the following common code snippet:
for i in range(len(li)):
pass
Could you see that if range()
went up to exactly len(li)
that this would be problematic? The programmer would need to explicitly subtract 1. This also follows the common trend of programmers preferring for(int i = 0; i < 10; i++)
over for(int i = 0; i <= 9; i++)
.
If you are calling range with a start of 1 frequently, you might want to define your own function:
>>> def range1(start, end):
... return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Is there a short way to check array size before going into for loop?
Drop the initial condition:
for i in 0..<json.count {
// Do something
}
If the range in the loop is impossible the code will not get executed.
Also, if you don't use i
inside the brackets you can replace it with _
.
Can range-based for loops be aware of the end?
The very purpose of range-based for loops is to forget the iterator. As such, they only allow you access to the current value and not the iterator. Would the following code do it for you?
set<int> S = {1,2,3,4};
std::string output;
for(auto &x: S) {
if (!output.empty())
output += ",";
output += to_string(x);
}
cout << output;
EDIT
Another solution: Instead of comparing iterators (as one would do with "normal" for loops), you could compare the addresses of the values:
set<int> S = {1,2,3,4};
auto &last = *(--S.end());
for (auto &x : S)
{
cout << x;
if (&x != &last)
cout << ",";
}
Related Topics
Slide Sidebar Menu iOS 8 Swift
How to Listen to Global Hotkeys With Swift in a Macos App
Appearance Proxies/Ui_Appearance_Selector in Swift
How to Refactor Swift in Xcode
How to Identify Uppercase and Lowercase Characters in a String with Swift
Add a Border with Cornerradius to an Image in Swiftui Xcode Beta 5
How to Set Exit Code Value for a Command Line Utility in Swift
How to Get Iobluetoothdevice's Battery Level, Using Swift and Appkit (Xcode for MACos)
How to Detect and Make Clickable Links in a Uilabel Not Using Uitextview
Swift - Reorder Uitableview Cells
iOS 13: Threading Violation: Expected the Main Thread
Call Parent Constructor When Init a Subclass in Swift
Skaction Completion Handlers; Usage in Swift
Mutating Function Inside Class
When Does the Copying Take Place for Swift Value Types