How to collect the return value of a function (Swift 3) - swift

Goal:
I want to collect the return value of a function.
Question:
How can I call the 'test' function to collect the return variable 'name' without passing through a parameter?
Is there a way to collect a variable(values) from functions with agruments(parameters) without passing through a parameter?
I have provided an example:
let userName = "Jake"
let userInfo = test(name: userName)
func test(name: String) -> String {
return name
}
// function call
// Goal: I want to retrieve the function return value without passing a parameter
let newUser = test()
Does the function 'test' return value have to be stored to retrieve it?
I want to retrieve the 'userName' Jake

You can return like below,
let userName = "Jake" //Global variable of the class
let userInfo = test() //Jake
func test() -> String { //single - element tuple will don't have label for return.
return self.userName
}
If you like to return with labels then you need tow or more return values like below,
func test() -> (name:String,age:Int) {
return (self.userName,125)
}
And access specific values by test().name

Related

Trouble creating a more complex closure

I am trying to get my head around creating closures. I get the simpler ones like:
let squaredNumber = { (num: Int) -> (Int) in
return num * num
}
print( squaredNumber(9) ) // 81
and I understand how the sorting one works:
let team = ["Bob", "Rick", "Peter"]
print( team.sorted() ) // ["Bob", "Peter", "Rick"]
print( team.sorted(by: { $0 > $1 }) ) //["Rick", "Peter", "Bob"]
So now I am trying to create my own version of sorting one, in terms of setup.
In the sorting one, there is a plain function sorted() and a sorted(by:...) option.
The code I am playing with so far is (commented code is just to play with):
struct Person {
let name_given = { (fn: String?, ln: String?) -> String in
// return a different value if a nil is supplied
guard let fn1 = fn else { return "No First Name" }
guard let ln1 = ln else { return "No Last Name" }
// Only returns value if not nil
// if let fn1 = fn { return fn1 }
// if let ln1 = ln { return ln1 }
// returns what has been decided above
return "\(fn!) \(ln!)"
}
let no_name = {() -> String in
return "Hello"
}
}
let dad = Person()
print( dad.name_given("Jeff", "Smith") )
print( dad.no_name() )
but I can only get this to work dad.something() but I would like the option of a parameter closure in a function that is I am guessing an optional.
Am I even on the right track in terms of thinking this through.
Basically I want to create a function that execute different code based on wether they have a parameter or not.
So something like dad() or dad(name: {"Jeff", "Smith"}) or dad(age: {35})
The closures would combine strings or do something with the code and then return the result or something.
There is no story to the code above, I just want to understand how to create it.
/////////////////
Edit for clarity:
So I realise my aim was explained with a lot of confusion, because I am trying to figure this out.
Here is hopefully a better attempt:
So this code still doesn't work, but bare with me.
Take for example this:
static func closure(both: (_ a: String, _ b: String) -> String { a, b in
return "\(a) \(b)"
})
and then this:
static func closure(single: (_ a: String) -> String { a in
return "\(a)"
})
So then I would effectively be able to do something like this:
Person.closure(both: {"First", "Last"}) -> This would output "First Last"
and
Person.closure(single: {"First"}) -> This would output "First"
My outcome would be that I could have a static class that has a bunch of closures, but that are grouped.
So if I want to a bunch of string type closures, it would be easy to find them because you could do something like:
StaticStruct.string(<thing1>: {<closure params>})
StaticStruct.string(<thing2>: {<closure params>})
StaticStruct.string(<thing3>: {<closure params>})
or if I want to do something with numbers, it would be:
StaticStruct.numbers(<thing1>: {<closure params>})
StaticStruct.numbers(<thing2>: {<closure params>})
StaticStruct.numbers(<thing3>: {<closure params>})
I hope this makes more sense.
I like the way it looks when you do an array sort, that is why I started thinking like this.
What you are asking is flawed for Swift:
If you don't provide anything at all, not even nil, how can Swift know what's missing?
Think about this example:
print( dad.name_given("Connor") )
How can Swift know if you provided only the first name, or only the last name? In your example, you will need to be specific on what is not provided:
print( dad.name_given(nil, "Connor") ) // Surely only last name is provided
A function would solve this problem by providing a default value to the parameters, so you don't have to pass nil, but then you would need to specifically tell what you're passing, or Swift will assume:
func person(fn: String? = "", ln: String? = "") -> String {...}
print( dad.person(ln: "Connor")) // Surely passing the second parameter
func person(_ fn: String? = "", _ ln: String? = "") -> String {...}
print( dad.person("Connor")) // It will assume that you are passing the first parameter
But with closures, you can't provide a default value to parameters:
let name_given = { (fn: String? = "", ln: String? = "") -> String in...}
// Error: Default arguments are not allowed in closures
It might not solve your problem, but you can create a function that provides default values to the parameters (no need to pass nil), and accepts a closure to treat those parameters.
func describe(fn: String = "", ln: String = "", _ action: #escaping (String?, String?)->String) -> String {
let first: String? = fn == "" ? nil : fn
let second: String? = ln == "" ? nil : ln
return action(first, second)
}
print( dad.describe(ln: "Connor", dad.name_given)) // No first Name

Do i have to state a "return nil" statement when my return value in a function is an optional?

So for example i have the following code:
var meals: [String: Meal] = ["Breakfast": Meal(food: ["Bagel", "Orange Juice", "Egg Whites"], calories: 530)]
func logging (mealTime: String) -> Meal? {
if let a = meals[mealTime] {
return a
} else {
return nil
}
}
Do i need to state a "return nil" if my return value is already an optional? Because the solution to this exercise was just this:
func logging(mealTime: String) -> Meal? {
return meals[mealTime]
}
And if I do not have to add the return nil, why is that?
Thanks in advance!
Just to clarify:
Parameter:
mealTime: String
This string could be a key in your dictionary.
Function (how it works): this function wants to check if this key exists and if it is so, it returns the value (that is a Meal object).
What did you do?
if let a = meals[mealTime] {
return a
} else {
return nil
}
You are checking (if let) if there is a value with that string key and you are assigning that value to your constant (a). Eventually you return that value. If no value has that key in your array then you return nil.
What is the right answer about?
Because this function returns an Optional Meal, you can skip checking if it exists, that's why the right answer is just:
func logging(mealTime: String) -> Meal? {
return meals[mealTime]
}
This function returns nil if there is not value with that key and returns the value if it has that key.

how can I return a result from a function into a variable?

I have a variable :
var name = [Nick,John,Peter]
and a function:
func name(){
var personname = []
.......
return personname
}
the result of the function are the names of the people Nick,John,Peter. How can I return the result into the variable.I mean I do not want to write the names manually I want to populate them from the function, because the function display all of the names. I am beginner and I will be glad if you show me the right syntaxis.
var name = [????] = [personname()] or how????
You should use -> to return something from a function. Here is an example:
static let people = ["Nick", "John", "Peter"]
func getPerson(index: Int) -> String
{
return self.people[index] //index is number of a person, 0 will be the first one, 1 is second, etc.
}
func showTeam()
{
// some code
print("This is a first boy: \(self.getPerson[0])")
// some code
}

Modifying struct instance using call to name in function parameter

I am attempting to use Parse to call up some variables and put them into a struct that is already initialized. The calling of the variables is happening smoothly and the data is available, but the inputing of the class into the function is not happening.
'unit' is a struct that has the name, hp, attack, etc. variables contained within it.
Is it not possible to pass along an instance of a struct and modify it's values like this? It would save me a lot of copy-pasting code to do it this way.
Thanks for your help!
func fetchStats(name: String, inout nameOfClass: unit) {
var unitStatArray = []
let query = PFQuery(className: "UnitStats")
query.whereKey("name", equalTo: name)
query.findObjectsInBackgroundWithBlock{(objects:[PFObject]?, error: NSError?)->Void in
if (error == nil && objects != nil){ unitStatArray = objects! }
nameOfClass.name = "\(unitStatArray[0].objectForKey("name")!)"
print("class name is \(nameOfClass.name)")
print("cannon name is \(cannon.name)")
nameOfClass.hitPoints = unitStatArray[0].objectForKey("hitPoints") as! Double
nameOfClass.hitPointsMax = unitStatArray[0].objectForKey("hitPointsMax") as! Double
nameOfClass.attack = unitStatArray[0].objectForKey("attack") as! Double
nameOfClass.defense = unitStatArray[0].objectForKey("defense") as! Double
nameOfClass.rangedAttack = unitStatArray[0].objectForKey("rangedAttack") as! Double
nameOfClass.rangedDefense = unitStatArray[0].objectForKey("rangedDefense") as! Double
nameOfClass.cost = unitStatArray[0].objectForKey("cost") as! Int
}
}
fetchStats("3-inch Ordnance Rifle", nameOfClass: &cannon)
This is an attempt to explain what I had in mind when writing my comment above.
Because there's an asynchronous call to findObjectsInBackgroundWithBlock, the inout won't help you here. The idea is to add a callback fetched like this:
func fetchStats(name: String, var nameOfClass: unit, fetched: unit -> ()) {
// your code as above
query.findObjectsInBackgroundWithBlock {
// your code as above plus the following statement:
fetched(nameOfClass)
}
}
This can be called with
fetchStats("3-inch Ordnance Rifle", nameOfClass: cannon) { newNameOfClass in
nameOfClass = newNameOfClass
}
(all of this code has not been tested)
The point is that you understand that your code is asynchronous (I know, I'm repeating myself). After you have called fetchStats you don't know when the callback (here: the assignment nameOfClass = newNameOfClass) will be executed. You cannot assume the assignment has been done after fetchStats has returned.
So whatever you need to do with the changed nameOfClass: the corresponding statements must go into the callback:
fetchStats("3-inch Ordnance Rifle", nameOfClass: cannon) { newNameOfClass in
// do whatever you want with the received newNameOfClass
}
Hope this helps.

Swift, Tuples issue #2

Sorry about the last thread where I posted this question by accident! Here it is. I received a response from someone (Their response is at bottom of page) and unfortunately it did not work. Thanks in advance!
Create a variable named result and assign it the tuple returned from function greeting. (Note: pass the string "Tom" to the greeting function.)
func greeting() -> (language: String, greeting: String, name: String) {
let language = "English"
let greeting = "Hello"
let name = "Tom"
return (language, greeting, name)
}
var result = greeting()
Error = Your function needs to return a tuple with elements named 'greeting' and 'language'.
Now this solution below tells me that my variable has the wrong value in it, but I can't figure out how to pass it "Tom" to the greeting function because I keep getting an error.
func greeting() -> (language: String, greeting: String) {
let language = "English"
let greeting = "Hello"
return (language, greeting)
}
var result = greeting("Tom")
Response I got in the last thread is below. I still get the error message saying that I need to assign the return value of greeting to result.
func greeting(name:String) -> (language: String, greeting: String) {
let language = "English"
let greeting = "Hello " + name + "!"
return (language, greeting)
}
var result = greeting("Tom").greeting
The task is
Create a variable named result and assign it the tuple returned from function greeting.
What you do in the last block is
var result = greeting("Tom").greeting
what I would expect you to do is
var result = greeting("Tom")