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]()
}
Related
Very new to Swift and coding in general.
Just need some help getting my random selector to work. I am trying to make it choose a random number between 1 and 9 and check if that number is the same as the button you click.
enter image description here
I'm guessing you're trying to compare the random number to the title (displayed number) on the clicked button?
If so, add this line above your if statement:
guard let buttonInt = sender.titleLabel?.text.flatMap(Int.init) else { return }
Then, change your if statement to look like so:
if randomNumber == buttonInt {
// do what you want if it matches
} else {
// handle no match
}
// EDIT: Props to Alexander for the flatMap version
Please check :
let rand = Int(arc4random_uniform(9))
guard let buttonInt = Int(sender.currentTitle!) else { return }
if rand == buttonInt {
} else {
}
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()
}
}
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 new to swift and trying to implement a simple function that takes minimum and max number as input and returns an array with all the numbers in the limit. I am getting an error
//Error: Reference to generic type 'Array' requires arguments in <...>
may I know what I am missing on?
func serialNumberLimits(minimumNumber n1:Int, maximumNumber n2:Int) -> Array {
// Initialized an empty array
var array = Int[]()
//Initialized a "Temp" variable
var temp:Int = 0
for index in n1..n2 {
temp += n1
n1++
if index == 1 { array.insert(temp, atIndex: 0) }
else { array.insert(temp, atIndex: index-1) }
}
return array
}
Use following function
1)As you are using n1 in function and changing its value so declare it as var as all parameters are constants in swift by default
2)Use Array<Int> as it needs to be define which type of array is in swift.Swift is strongly typed language so all type need to be defined.
Run following code it will compile with no errors
func serialNumberLimits(var minimumNumber n1:Int, maximumNumber n2:Int) -> Array<Int> {
// Initialized an empty array
var array = Int[]()
//Initialized a "Temp" variable
var temp:Int = 0
for index in n1..n2 {
temp += n1
n1++
if index == 1 { array.insert(temp, atIndex: 0) }
else { array.insert(temp, atIndex: index) }
}
return array
}
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 {
...
}