When running my code, I am getting a number of 1's printing to the console rather than 1,2,3,4,5....
Some help with why this is happening would be great, I'm having trouble figuring it out.
The idea is to loop through the Calendar names until finding the 'Travel' calendar.
func checkCalendarExists(){
var eventCalendars = store.calendarsForEntityType(EKEntityTypeEvent) as [EKCalendar]
for i in eventCalendars {
var count = 0
var calendarCount = eventCalendars.count
if i.title != "Travel" && count != calendarCount
{
++count
println(count)
}
else if i.title == "Travel"
{
// do something
}
else
{
aMethod()
}
}
}
Your count variable is not being incremented because it is declared inside the loop and initialized to the value zero at the beginning of each iteration. For your code to work as expected you have to move var count = 0 outside the for loop.
Your count variable does get incremented, but it resets to zero every time the for loop runs its sequence.
It's always advised to declare and assign incrementing variables outside loops.
Please change your code to (I am initializing var count = 0 before the loop)
func checkCalendarExists(){
var eventCalendars = store.calendarsForEntityType(EKEntityTypeEvent) as [EKCalendar]
var count = 0
for i in eventCalendars {
var calendarCount = eventCalendars.count
......
......
......
else
{
aMethod()
}
}
}
ALXGTV's answer explains why you have that unexpected behavior.
Your code can be optimized though - rather than manually handling a counter variable, I recommend using the enumerate function, which returns a (index, value) at each iteration:
for (index, calendar) in enumerate(eventCalendars) {
...
}
Also this variable:
var calendarCount = eventCalendars.count
is populated at each iteration, always with the same value. It would be more efficient if it is moved before the loop, making it immutable:
let calendarCount = eventCalendars.count
for (index, calendar) in enumerate(eventCalendars) {
...
}
Last, I would prefer using a flag for the not found condition, handling it outside the loop:
func checkCalendarExists() {
var eventCalendars = store.calendarsForEntityType(EKEntityTypeEvent) as [EKCalendar]
var found = false
let calendarCount = eventCalendars.count
for (index, calendar) in enumerate(eventCalendars) {
if calendar.title == "Travel" {
// do something
found = true
break // This stops the loop
} else {
println(index + 1)
}
}
if !found {
aMethod()
}
}
Related
private var oneAndOnly {
get {
let faceCardIndices = cards.indices.filter({cards[$0].isFaceUp})
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
}
}
vs
private var oneAndOnly {
get {
return cards.indices.filter({cards[$0].isFaceUp}).first
}
}
If .first returns nil anyway when there is no element, I would assume that these are equivalent but they are not. The first block actually gives me a new index where as the second block gets stuck.
The difference is that the first block will find the index of the flipped card only if there is exactly one such card.
The second block will return the index of the first card that is flipped, even if there are multiple such cards.
In other words for:
faceCardIndices = [5]
both methods will return 5 but for:
faceCardIndices = [1, 5]
the first will return nil while the second will return 1.
In all other aspects the methods are equivalent.
On this line:
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
if faceCardIndices.count is NOT equal to 1, then faceCardIndices.first does not even get evaluated... it simply returns nil.
With your other code:
return cards.indices.filter({cards[$0].isFaceUp}).first
it will try to get .first, regardless of the result of .filter ... and that can lead to trying to get the first element of zero elements.
They appear to be equivalent functions when cards is an empty array, with both functions returning nil.
In playgrounds:
struct Card {
var isFaceUp: Bool
}
struct Test {
var cards = [Card]()
var oneAndOnly: Int? {
get {
let faceCardIndices = cards.indices.filter({cards[$0].isFaceUp})
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
}
}
var oneAndOnly2: Int? {
get {
return cards.indices.filter({cards[$0].isFaceUp}).first
}
}
}
var test = Test()
test.oneAndOnly //nil
test.oneAndOnly2 //nil
Also, when cards contains 4 cards, with one face up, both functions return the same index of 2.
var test = Test()
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: false))
test.oneAndOnly //2
test.oneAndOnly2 //2
The difference comes into play when the array contains more than 1 face up card, with the first function returning nil and the second function returning the index of the first face up card. This is due to the faceCardIndices.count == 1 constraint that is only used in the first function.
var test = Test()
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: false))
test.oneAndOnly //nil
test.oneAndOnly2 //1
I've got a question on property observers. There's some example code below. What I want is for the property Analysis.hasChanged to be updated to true if a.value is changed. Is there a way I can do this?
class Number {
var value: Double
init(numberValue: Double) {
self.value = NumberValue
}
}
class Analysis {
var a: Number
var hasChanged = false
init(inputNumber: Number) {
self.a = inputNumber
}
}
testNumber = Number(numberValue: 4)
testAnalysis = Analysis(inputNumber: testNumber)
print(testAnalysis.hasChanged) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged) // will still print "false", but I want it to print "true"
In the end, I want the user to be able to be notified if any of their analyses use numbers that have been changed so that they can update the results of the analyses if they choose.
You can use the built-in property observers provided by Swift.
Every time you set a new value, the didSet will be called. You just need to attach the closure, wrapping the desired behaviour, to the Number class
class Number {
var valueDidChangeClosure: (()->())?
var value: Double {
didSet {
//won't call the valueDidChangeClosure
//if the value was changed from 10 to 10 for example..
if oldValue != value {
valueDidChangeClosure?()
}
}
}
init(numberValue: Double) {
self.value = numberValue
}
}
class Analysis {
var a: Number
var hasChanged = false
init(inputNumber: Number) {
self.a = inputNumber
self.a.valueDidChangeClosure = {
self.hasChanged = true
}
}
}
let testNumber = Number(numberValue: 4)
let testAnalysis = Analysis(inputNumber: testNumber)
print(testAnalysis.hasChanged) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged) // will print "true"
I would do something like this, I apologize in advance if I have some syntax wrong (I usually use C/C++, think of this as more psudo code since you'd have to have a way to copy Number classes, etc.).
class Number {
var value: Double
init(numberValue: Double) {
self.value = NumberValue
}
}
class Analysis {
var a: Number
var _a: Number
bool hasChanged() {
if (a != _a) {
_a = a
return true;
}
return false;
}
init(inputNumber: Number) {
self.a = inputNumber
self._a = self.a
}
}
testNumber = Number(numberValue: 4)
testAnalysis = Analysis(inputNumber: testNumber)
print(testAnalysis.hasChanged()) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged()) // will still print "false", but I want it to print "true"
In the end, I want the user to be able to be notified if any of their analyses use numbers that have been changed so that they can update the results of the analyses if they choose.
I don't know if this really addresses that question, I based my answer off of the code you provided. So there may be additional functionality if you want there to be some triggering method (instead of calling .hasChanged()).
Comparing doubles (and any other floating point type) with '=' or '!=' is not a good idea.
Use epsilon function instead.
Details: jessesquires.com/blog/floating-point-swift-ulp-and-epsilon/
I got 3 different functions and I want to call one of these randomly.
if Int(ball.position.y) > maxIndexY! {
let randomFunc = [self.firstFunction(), self.secondFunction(), self.thirdFunction()]
let randomResult = Int(arc4random_uniform(UInt32(randomFunc.count)))
return randomFunc[randomResult]
}
With this code I call all functions, and the order is always the same. What can I do to just call one of these?
The reason the three functions are called (and in the same order) is since you are causing them to be called when you put them in the array.
This:
let randomFunc = [self.firstFunction(), self.secondFunction(), self.thirdFunction()]
Stores the return value of each function in the array since you are invoking them (by adding the '()').
So at this point randomFunc contains the return values rather than the function closures
Instead just store the functions themselves with:
[self.firstFunction, self.secondFunction, self.thirdFunction]
Now if you want to call the selected method do not return its closure but invoke it:
//return randomFunc[randomResult] // This will return the function closure
randomFunc[randomResult]() // This will execute the selected function
if Int(ball.position.y) > maxIndexY! {
let randomNumber = Int.random(in: 0...2)
if randomNumber == 0 {
firstFunction()
} else if randomNumber == 1 {
secondFunction()
} else if randomNumber == 2 {
thirdFunction()
}
}
I expect it should work
if Int(ball.position.y) > maxIndexY! {
let randomFunc = [self.firstFunction, self.secondFunction, self.thirdFunction]
let randomResult = Int(arc4random_uniform(UInt32(randomFunc.count)))
return randomFunc[randomResult]()
}
I am trying to access "numOne" right before the return statement and I can't seem to find why it is not working. Everything was fine accessing "numTwo". Is the reason because "numOne" is inside a range?
func checknumber() -> String {
var numTwo = 0
var range = 0...b
for numOne in range {
numTwo = b-numOne
if let result = isCommon(numOne: numOne, numTwo: numTwo) {
println("Success - \(numOne) and \(numTwo) Work")
break
} else {
println("Failure - \(numOne) and \(numTwo) Does NOT Work")
}
var numOneFinal = numOne
}
var numberTwo = "\(numTwo)"
var numberOne = "\(numOneFinal)"
return numberTwo
}
If anyone could point me in the right direction that would be greatly appreciated.
numOne is scoped by the for statement in which it is defined.
To gain access to the last value of numOne after the loop, add a new variable, say numOneFinal, at the same level as numTwo, then assign numOne's value to it within the for loop.
You can't access numOne outside of the for loop, because it's out of the scope. You can only access numOne within the loop
I am getting the error:
Immutable value of type 'Array Character>' only has mutating members of name removeAtIndex()
The array should have contents because that removeAtIndex line is in a loop who's condition is if the count > 1
func evaluatePostFix(expression:Array<Character>) -> Character
{
var stack:Array<Character> = []
var count = -1 // Start at -1 to make up for 0 indexing
if expression.count == 0 {
return "X"
}
while expression.count > 1 {
if expression.count == 1 {
let answer = expression[0]
return answer
}
var expressionTokenAsString:String = String(expression[0])
if let number = expressionTokenAsString.toInt() {
stack.append(expression[0])
expression.removeAtIndex(0)
count++
} else { // Capture token, remove lefthand and righthand, solve, push result
var token = expression(count + 1)
var rightHand = stack(count)
var leftHand = stack(count - 1)
stack.removeAtIndex(count)
stack.removeAtIndex(count - 1)
stack.append(evaluateSubExpression(leftHand, rightHand, token))
}
}
}
Anyone have any idea as to why this is? Thanks!
Because all function parameters are implicitly passed by value as "let", and hence are constant within the function, no matter what they were outside the function.
To modify the value within the function (which won't affect the value on return), you can explicitly use var:
func evaluatePostFix(var expression:Array<Character>) -> Character {
...
}