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.
它应该具有类型为[Circle]的私有属性。圈的数组。该方法去除半径大于最小要求、小于最大要求的圆。
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".
显然,我应该使用removeAtIndex()删除不满足循环中确定的条件的数组项。然而,在删除循环中的项之前,许多人已经指出,因为我猜是“迭代器/索引不匹配”。
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.
最终,我创建了一个空数组,并使用.append()来将满足“良好”条件的值推到filteredCircles数组中,但我不得不感到,这并不符合赋值的标准。
Is there a solution that actually removes the items from the array in a loop?
是否有一个解决方案可以在循环中从数组中删除项?
2 个解决方案
#1
9
If the FOR LOOP
is not mandatory (and I don't see this requirement in the quoted text) you should use the filter
method.
如果FOR循环不是强制性的(我在引用的文本中没有看到这个要求),您应该使用filter方法。
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 }
Why this approach is better than mutating the array in a FOR LOOP
- Since
circles
is a constant, you don't have problems related to multithreading programming. Ifcircles
was mutable then other threads could change it while you are looping it with very scary side effects. - 因为圆是常量,所以您不会遇到与多线程编程相关的问题。如果圆圈是可变的,那么其他线程可以在循环时更改它,这会产生非常可怕的副作用。
- It's less error prone. You are not writing what the CPU should do, instead you are describing how the results should be. So less potential misunderstandings between you and the compiler :)
- 这是不容易出错。您不是在编写CPU应该做什么,而是在描述结果应该如何。这样你和编译器之间的潜在误解就会减少
- You are writing less code which does mean less potential mistakes.
- 你写的代码更少了,这意味着更少的潜在错误。
These are some of the benefits of writing Functional Programming code.
这是编写函数式编程代码的一些好处。
#2
1
To elaborate in @vacawama's answer:
在@vacawama的回答中详述:
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:
如果你想用Double表示你的圆的半径,但是想要保持漂亮的语法:
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)
}
}
}
}
#1
9
If the FOR LOOP
is not mandatory (and I don't see this requirement in the quoted text) you should use the filter
method.
如果FOR循环不是强制性的(我在引用的文本中没有看到这个要求),您应该使用filter方法。
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 }
Why this approach is better than mutating the array in a FOR LOOP
- Since
circles
is a constant, you don't have problems related to multithreading programming. Ifcircles
was mutable then other threads could change it while you are looping it with very scary side effects. - 因为圆是常量,所以您不会遇到与多线程编程相关的问题。如果圆圈是可变的,那么其他线程可以在循环时更改它,这会产生非常可怕的副作用。
- It's less error prone. You are not writing what the CPU should do, instead you are describing how the results should be. So less potential misunderstandings between you and the compiler :)
- 这是不容易出错。您不是在编写CPU应该做什么,而是在描述结果应该如何。这样你和编译器之间的潜在误解就会减少
- You are writing less code which does mean less potential mistakes.
- 你写的代码更少了,这意味着更少的潜在错误。
These are some of the benefits of writing Functional Programming code.
这是编写函数式编程代码的一些好处。
#2
1
To elaborate in @vacawama's answer:
在@vacawama的回答中详述:
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:
如果你想用Double表示你的圆的半径,但是想要保持漂亮的语法:
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)
}
}
}
}