Cannot assign to value: 'k' is a 'let' constant - swift

I am solving a problem and , i have to decrease the value of k which is a parameter in a function , but when i am decreasing the value of k it says Cannot assign to value: 'k' is a 'let' constant
Here is the code
var count:Int = 0
func maximumToys(prices: [Int], k: Int) {
for i in prices {
if i < k {
k = k - i
}
} }

You can use inout keyword. Try this:
func maximumToys(prices: [Int], k: inout Int) {
for i in prices {
if i < k {
k = k - i
}
}
}
An example usage:
var prices = [Int]()
prices.append(1)
prices.append(2)
var k = 4;
maximumToys(prices: prices, k: &k)

In Swift, variables in functions are by default constants and copies of the original value (assuming they're structs, as is the case with Ints).
There are two ways around this:
You can either declare a variable copy within the body of the function, and then you can return k:
func maximumToys(prices: [Int], k: Int) -> Int {
var k = k
...
return k
}
Or you can use the inout keyword on the variable. If you use the inout keyword, be aware that you are going to be modifying the original value. This makes your code no longer thread safe, as multiple accesses of the same memory path can lead to undefined behavior.

if the variable is coming from parameter just use inout keyword before variable name like this
func convertToBytes(bytesToSave : inout [UInt64])

Yes, you cannot update a value of ‘k’
Just use a temp variable
var count:Int = 0
func maximumToys(prices: [Int], k: Int) -> Int {
var j = k //temp variable
for i in prices {
if i < j {
J = j - i
}
}
return j
}
let result = maximumToys(prices: [10,20], k: 30)

Related

Swift 2.1 Closure

At first, I apologize for my English!
Please help me detect when I was wrong.
let arrayInt = [0, 1, 2, 3, 4, 5, 7, 8, 9]
func myF(array: [Int], cl:(n1: Int, n2: Int) -> Bool) -> Int {
var number : Int
for value in array {
if cl(n1: number, n2: value) {
number = value
}
}
return number
}
myF(arrayInt, { cl: (n1: Int, n2: Int) -> Bool in
return n1 < n2
})
The function takes an array of Int and closure returns Int. Closure should take two Int numbers and return Bool yes or no. It is necessary to walk in a loop through the array and compare elements of array with variable using closure . If closure returns yes, you write the value of the array into variable. At the end of the function returns the variable. We need find max and min value in array.
I have 3 issue:
consecutive statements on a line must be separated by ';'
expected expression
contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored
Please don't proposed me use method "sort()". I am learning of "closure".
First of all you need to initialize your number variable: var number : Int -> var number = 0
Second, the function call with closure is not correct. There are several ways to call a closure:
let y = myF(arrayInt, cl: { (n1: Int, n2: Int) -> Bool in
return n1 < n2
})
or
let x = myF(arrayInt) { (n1, n2) -> Bool in
return n1 < n2
}
or even
let z = myF(arrayInt) { n1, n2 in
return n1 < n2
}
and
let w = myF(arrayInt) { $0 < $1 }
This link and this one should help you
Full code sample:
let arrayInt = [1, 2, 3, 0, 4]
func myF(array: [Int], cl: (n1: Int, n2: Int) -> Bool) -> Int {
var number = 0
for i in array {
if cl(n1: number, n2: i) {
number = i
}
}
return number
}
let x = myF(arrayInt) { (n1, n2) -> Bool in
return n1 < n2
}
First replace:
myF(arrayInt, { cl: (n1: Int, n2: Int) -> Bool in
by:
myF(arrayInt, cl: { (n1: Int, n2: Int) -> Bool in
because cl is the parameter name and all included in { } is the closure.
Second initialize number in myF function replacing:
var number : Int
by:
var number = array[0]
if the goal of the closure is to find max or min value.

Im confused on how this function is being called, there is no call for it?

I'm confused on how getFunctionNeededForReference is running. There is no call for it and where are the functions returned to? where are they going? I know they are being referenced but where are the functions going to, there is not call for getFunctionNeededForReference in the beginning? there is no call sending the argument flag anyway?
func add ( a: Int , b : Int)-> Int {
//returing a result and not a variable
return a + b
}
func multiply ( a: Int, b: Int) -> Int{
return a * b
}
// declaring a function as a variable, it takes in 2 Ints and returns an Int
var f1 : (Int, Int)-> Int
f1 = add
f1 = multiply
// Function as a parameter
func arrayOperation (f: (Int, Int) -> Int , arr1: [Int] , arr2: [Int]) -> [Int]
{
// Declaring and initializing an empty array to return
var returningArray = [Int]()
for (i, val) in enumerate(arr1)
{
returningArray.append(f(arr1 [i], arr2 [i]))
}
return returningArray
}
arrayOperation(add, [2,3,4], [4,5,6])
arrayOperation(multiply, [2,3,4], [4,5,6])
//Function as a return value
func getFunctionNeededForReference (flag : Int) -> (Int,Int) ->Int
{
if flag == 0 {
return add
}else {
return multiply
}
}
What you've posted is just some example code showing things that Swift supports. It's not code that's useful for anything. It's just demonstrating Swift's syntax for first-class functions.
If you don't understand what “first-class functions” means, you can look up the term in your favorite search engine and find many explanations.

How do you overload an operator in swift?

Say you have a class C. It has two instance variables, number and vector. vector is just an array of either ints or doubles.
I would like to do the following:
c1 = C()
c1.number = 2
c1.vector = [1,2,3]
c2 = C()
c2.number = 3
c2.vector = [4,6,7]
println(c1.number + c2.number) \\print to screen 5
println(c1.vector + c2.vector) \\ print [5,8,10]
Basically, I'm looking to overload the "+" operator so that it knows which "version" of the "+" to use depending of the type.
The + operator is already defined for the type Array. It does an array merge and tacks the values of the rvalue onto the lvalue. To do a sum of values by index you can do something like this:
protocol Numeric { }
extension Double: Numeric {}
extension Int: Numeric {}
func +<T: Numeric>(left: [T], right: [T]) -> [T]? {
var numElements: Int = 0
if count(left) != count(right) {
return nil
} else {
numElements = count(left)
}
var result = [T]()
for var i = 0; i < numElements; ++i {
if let lvalue = left[i] as? Int, rvalue = right[i] as? Int {
result.append(lvalue + rvalue as! T)
} else if let lvalue = left[i] as? Double, rvalue = right[i] as? Double {
result.append(lvalue + rvalue as! T)
}
}
return result
}
But generally, I wouldn't advise overriding a predefined operator because of the high potential to cause confusion and chaos later on down the road.

Swift: reusing a closure definition (with typealias)

I'm trying to do create some closure definitions which I'm gonna use a lot in my iOS app. So I thought to use a typealias as it seemed the most promising ...
I did a small Playground example which shows my issue in detail
// Here are two tries for the Closure I need
typealias AnonymousCheck = (Int) -> Bool
typealias NamedCheck = (number: Int) -> Bool
// This works fine
var var1: AnonymousCheck = {
return $0 > 0
}
var1(-2)
var1(3343)
// This works fine
var var2: NamedCheck = {
return $0 > 0
}
var2(number: -2)
var2(number: 12)
// But I want to use the typealias mainly as function parameter!
// So:
// Use typealias as function parameter
func NamedFunction(closure: NamedCheck) {
closure(number: 3)
}
func AnonymousFunction(closure: AnonymousCheck) {
closure(3)
}
// This works as well
// But why write again the typealias declaration?
AnonymousFunction({(another: Int) -> Bool in return another < 0})
NamedFunction({(another: Int) -> Bool in return another < 0})
// This is what I want... which doesn't work
// ERROR: Use of unresolved identifier 'number'
NamedFunction({NamedCheck in return number < 0})
// Not even these work
// ERROR for both: Anonymous closure arguments cannot be used inside a closure that has exlicit arguments
NamedFunction({NamedCheck in return $0 < 0})
AnonymousFunction({AnonymousCheck in return $0 < 0})
Am I missing something or is it just not supported in Swift?
Thanks
EDIT/ADDITION:
The above is just a simple example. In real life my typealias is more complicated. Something like:
typealias RealLifeClosure = (number: Int, factor: NSDecimalNumber!, key: String, upperCase: Bool) -> NSAttributedString
I basically want to use a typealias as a shortcut so I don't have to type that much. Maybe typealias isn't the right choice... Is there another?
You aren't rewriting the typealias declaration in this code, you're declaring the parameters and return type:
AnonymousFunction({(another: Int) -> Bool in return another < 0})
Happily, Swift's type inference lets you use any of the following - pick the style that feels best to you:
AnonymousFunction( { (number: Int) -> Bool in number < 0 } )
AnonymousFunction { (number: Int) -> Bool in number < 0 }
AnonymousFunction { (number) -> Bool in number < 0 }
AnonymousFunction { number -> Bool in number < 0 }
AnonymousFunction { number in number < 0 }
AnonymousFunction { $0 < 0 }
I don't think you'll be able to do what you want. To simplify your example slightly, you can do this:
typealias NamedCheck = (number: Int) -> Bool
let f: NamedCheck = { $0 < 5 }
f(number: 1)
NamedFunction(f)
NamedFunction( { $0 < 5 } as NamedCheck)
But you can't do what you want, which is to rely on the fact that the tuple arg is called number to refer to it inside the closure without giving it as part of the closure:
// compiler error, no idea what "number" is
let g: NamedCheck = { number < 5 }
Bear in mind that you can name the parameter without giving it a type (which is inferred from the type of g):
let g: NamedCheck = { number in number < 5 }
but also, you can name it whatever you want:
let h: NamedCheck = { whatevs in whatevs < 5 }
NamedFunction(h)
Here's what I think is happening (this is partly guesswork). Remember how functions can have external and internal argument names:
func takesNamedArgument(#namedArg: Int) { etc... }
Or, to write it longhand:
func takesNamedArgument(namedArg namedArg: Int) { etc... }
But you can also give as the second, internal, name whatever you like:
func takesNamedArgument(namedArg whatevs: Int) { etc... }
I think this is what is happening with the closures with named tuples. The "external" name is "number", but you must give it an "internal" name too, which is what you must use in the function body. You can't make use of the external argument within your function. In case of closure expressions, if you don't give an internal name, you can use $0 etc, but you can't just skip it, any more than you can skip the internal name altogether and just rely on the external name when defining a regular function.
I was hoping that I could prove this theory by the following:
let f = { (#a: Int, #b: Int)->Bool in a < b }
resulting in f being of type (a: Int, b: Int)->Bool). This compiles, as does:
let g = { (number1 a: Int, number2 b: Int)->Bool in a < b }
but it doesn't look like the external names for the argument make it out to the type of f or g.
The syntax to create a closure is:
{ (parameters) -> return type in
statements
}
What's at the left of in is the closure signature (parameters and return value). In some cases the signature can be omitted or simplified when type inference is able to determine the number of parameters and their type, and the return value.
In your case it doesn't work because you are passing a type alias, but it is interpreted as a parameter name. The 3 lines work if either you:
name the parameter properly
NamedFunction({number in return number < 0})
AnonymousFunction({number in return number < 0})
use shorthand arguments:
NamedFunction({ return $0 < 0})
AnonymousFunction({ return $0 < 0})
use shorthand arguments and implicit return:
NamedFunction({ $0 < 0})
AnonymousFunction({ $0 < 0})

'Int' is not identical to 'UInt8' in closure

I am trying to create a closure that keeps a reference to the local variable of the outer function and I keep getting this ambigious error int is not identical to unint8. It does not make sense to me because there no arrays involved here. There are also no UInt8s involved here too.
func increment(n:Int)-> ()->Int {
var i = 0
var incrementByN = {
() -> Int in
i += n
}
return incrementByN
}
var inner = increment(4)
inner()
inner()
inner()
I found that I can fix this by returning i after i+=n. I thought that i+=n would return on it's own but apparently it does not.
+= for (Int, Int) is declared as
func +=(inout lhs: Int, rhs: Int)
It returns nothing.
I don't know why UInt8 involves, though.
Maybe, it's because func +=(inout lhs: UInt8, rhs: UInt8) is the last one of func +=(...) declarations.
Not sure what the UInt8 is about, but it seems that += does not have a value.
var i = 1;
let x = i += 3; // now x is of type ()
You can explicitly return the new value of i:
var incrementByN = {
() -> Int in
i += n
return i
}