Reputation: 2923
Full disclose, this is for a homework question:
It should have a private property of type [Circle]. An array of circles. The method should remove any circles that have a radius larger than the minimum requirement, and smaller than the max requirement.
It seems obvious that I should use removeAtIndex()
to remove array items that don't meet a condition determined in the loop. However, many have pointed out before the perils of removing items in a loop because of what I guess is a "iterator/index mismatch".
Ultimately I ended up creating an empty array and using .append()
to push the values that meet the "good" condition to a filteredCircles
array, but I can't help but to feel that this this doesn't meet the criteria for the assignment.
Is there a solution that actually removes the items from the array in a loop?
Upvotes: 13
Views: 8126
Reputation: 59526
If the FOR LOOP
is not mandatory (and I don't see this requirement in the quoted text) you should use the filter
method.
When you invoke filter
on an array you get a new array containing only the values that do respect the closure you passed to filter
. The original array is not mutated.
struct Circle {
let radius: Double
}
let circles = [Circle(radius: 1), Circle(radius: 5.1), Circle(radius: 4), Circle(radius: 10.8)]
let bigCircles = circles.filter { $0.radius > 5 }
circles
is a constant, you don't have problems related to multithreading programming. If circles
was mutable then other threads could change it while you are looping it with very scary side effects.These are some of the benefits of writing Functional Programming code.
Upvotes: 14
Reputation: 3268
To elaborate in @vacawama's answer:
struct Circle {
var radius: Int
}
struct MyStruct {
private var circles: [Circle]
mutating func removeCirclesWithRadiusWithin(range: Range<Int>) {
for index in (circles.startIndex..<circles.endIndex).reverse() {
if range.contains(circles[index].radius) {
circles.removeAtIndex(index)
}
}
}
}
If you want to use Double
for your Circle
's radius
, but want to keep the nice syntax:
struct Circle {
var radius: Double
}
struct MyStruct {
private var circles: [Circle]
mutating func removeCirclesWithRadiusWithin<I: IntervalType where I.Bound == Double>(interval: I) {
for index in (circles.startIndex..<circles.endIndex).reverse() {
if interval.contains(circles[index].radius) {
circles.removeAtIndex(index)
}
}
}
}
Upvotes: 1