Reputation: 3301
I have an array as a property in a class.
Class Custom {
let objArray: [CustomClass]
}
I want to remove some items in objArray in a range. So I have done below
let newVar = objArray[1...3]
new objects are correctly removed but return value is in newVar since array is value type how I can make the original reflect the same.
Below code gets Index out of bounds as the indexes incremented
for i in 1...3 {
objArray.remove(at: 1)
}
======
What is the best approach for the above issue.
Any hint in right direction would be highly appreciated.
Upvotes: 9
Views: 14080
Reputation: 285072
If you want to remove items by index in a range you have to inverse the indexes to start with the highest index otherwise you will get the out-of-range exception. Consider also that indexes are zero-based.
That's a safe version which checks also the upper bound of the array.
var array = [1, 2, 3, 4, 5, 6]
for i in (0...3).reversed() where i < array.count {
array.remove(at: i)
}
print(array) // [5, 6]
You can find a more generic and more efficient solution here
Upvotes: 5
Reputation: 5569
extension Array {
/**
* ## Examples:
* var arr = [0,1,2,3]
* arr.remove((0..<2)) // 0,1
* arr // 2,3
*/
mutating func remove(_ range: Range<Int>) -> Array {
let values = Array(self[range])
self.removeSubrange(range)
return values
}
}
Upvotes: 2
Reputation: 3428
The issue you are having is that an array index is zero based, which is to say, the first element in an array is accessed bv:
Let firstArrayValue = objArray[0]
So in the case of your for loop, you need to subtact 1 from i to get the proper index value:
for i in 1…3 {
objArray.remove(at: i-1) }
A better way is to loop through the indices by starting at 0. i = 0 will reference the first value in your objArray:
for i in 0...2 {
objArray.remove(at: i)
}
If you need to remove elements in the middle of the array you must first find their index location then remove. To find the index:
let indexLocation = objArray(indexOf: "Value in Array")
Then remove:
objArray.remove(at: indexLocation)
Upvotes: 0
Reputation: 13354
Use removeSubrange
method of array. Make a valid range
by element location
and length
.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let range = 1...3
array.removeSubrange(range)
print(array)
Output: [1, 5, 6, 7, 8, 9, 10]
Note: Range should be a valid range I mean it should not be out from array.
Here is yours way (by for loop) We can not remove objects by their indexes in a loop because every time object removes array's count and objects indexes will be change so out of range crash can come or you might get a wrong output. So you will have to take help of another array. See below example:-
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var newArray: [Int] = []
let minRange = 1
let maxRange = 3
for i in 0..<array.count {
if i >= minRange && i <= maxRange {
/// Avoid
continue
}
newArray.append(array[i])
}
print(newArray)
Output: [1, 5, 6, 7, 8, 9, 10]
Upvotes: 23