How to make a custom function with + operator in Swift [duplicate] - ios

This question already has answers here:
Member operator '%' must have at least one argument of type 'ViewController’
(2 answers)
Closed 1 year ago.
I'm looking at this code from rosettacode.org and one of the functions defined within it is this:
class MyClass {
static func + <T>(el: T, arr: [T]) -> [T] {
var ret = arr
ret.insert(el, at: 0)
return ret
}
}
The compiler has this to say about it:
Member operator '+' must have at least one argument of type 'MyClass'
I updated the method to make it it static, as follows:
static func + <T: Sequence>(el: T, arr: [T]) -> [T] {
var ret = arr
ret.insert(el, at: 0)
return ret
}
That doesn't get rid of the compiler error. I tried Googling it, but I'm not coming up with any short, simple answers. Any ideas how I might quell this error?

As explained by #MartinR in the comments, you need to put this function at the top level (NOT inside a class).
import Foundation
// Will compile fine from here as is
func + <T>(el: T, arr: [T]) -> [T] {
var ret = arr
ret.insert(el, at: 0)
return ret
}
class TableGenerator {
// will require at least one argument of the function to be of `TableGenerator` type
}

Related

what's the 'Int -> Int' type ? when a function as a return value? [duplicate]

This question already has answers here:
What does the type ((Int) -> Int) mean in Swift?
(3 answers)
Closed 7 years ago.
func makeIncrementer() -> (Int ->Int) {
func addOne(number:Int) ->Int {
return 1 + number
}
return addOne // result`enter code here`:Int -> Int
}
var increment = makeIncrementer() // result:`enter code here`Int -> Int
increment(7) // result`enter code here`8
I can't understand it how to implement !
In swift a function can return another function.
The following statement:
func makeIncrementer() -> (Int ->Int)
means the makeIncrement function will return another function which has an argument type of Int and it returns an Int
In the above case, the makeIncrementer function returns the addOne function and then you are calling it by passing a value of 7. (It is somewhat similar a function that returns a function pointer in C language)
You can read more about these kind of functions here : Function Types as Return Types

What should my Array+RemoveObject.Swift contain?

I am using a template project to try to build a new app. When I run the template project, I get an error saying: '[T] does not have a member named 'indexOf'.
The existing code in the Array+RemoveObject.swift doc is:
import Foundation
public func removeObject<T: Equatable>(object: T, inout fromArray array: [T])
{ let index = array.indexOf(object)
if let index = index {
array.removeAtIndex(index)
}
}
Is the problem the use of indexOf? The odd thing is that when I tried using the solution of someone who answered a similar question, I got around 100 errors from the bond framework.
You function on its own works fine for me (Swift 2.1.1, Xcode 7.2). It seems as if you want this function to be a method of a public class of yours. For a minimum working example, you need at least to wrap your removeObject() method within the class you want it to belong to. Note also that you needn't use a separate line for assigning the result from .indexOf(..) call (possibly nil), but can add assignment and nil check in a single if let statement.
public class MyArrayOperations {
// ...
static public func removeObject<T: Equatable>(object: T, inout fromArray array: [T]) {
if let index = array.indexOf(object) {
array.removeAtIndex(index)
}
}
}
var arr = ["1", "2","3"]
MyArrayOperations.removeObject("2", fromArray: &arr)
print(arr) // ["1", "3"]
Also note that you can explicitly state the same behaviour using two generics, in case you want the array itself to conform to some protocol. You then use one separate generic for the array type and one for its elements, thereafter specifying that the element type should conform to the Generator.Element type of the array. E.g.:
func removeObject<T: Equatable, U: _ArrayType where U.Generator.Element == T>(object: T, inout fromArray array: U) {
if let index = array.indexOf(object) {
array.removeAtIndex(index)
}
}
With this approach, you could add an additional protocol at type constraint for the array generic U in the function signature above, e.g.
func removeObject<T: Equatable, U: protocol<_ArrayType, MyProtocol> where U.Generator.Element == T>(object: T, inout fromArray array: [T]) { ...
This can be especially useful when "simulating" generic Array extensions that conforms to some protocol. See e.g. the following for such an example:
extend generic Array<T> to adopt protocol

Generic Function without Input Parameter in Swift?

I have a generic Swift function like this:
func toNSArray<T>() -> [T] {
...
}
The compiler gives no error but I do not know how to call this function. I tried:
jList.toNSArray<String>()
jList.<String>toNSArray()
but it did not work.
How do I call a Generic function in Swift without input parameters?
You need to tell Swift what the return type needs to be through some calling context:
// either
let a: [Int] = jList.toNSArray()
// or, if you aren’t assigning to a variable
someCall( jList.toNSArray() as [Int] )
Note, in the latter case, this would only be necessary if someCall took a vague type like Any as its argument. If instead, someCall is specified to take an [Int] as an argument, the function itself provides the context and you can just write someCall( jList.toNSArray() )
In fact sometimes the context can be very tenuously inferred! This works, for example:
extension Array {
func asT<T>() -> [T] {
var results: [T] = []
for x in self {
if let y = x as? T {
results.append(y)
}
}
return results
}
}
let a: [Any] = [1,2,3, "heffalump"]
// here, it’s the 0, defaulting to Int, that tells asT what T is...
a.asT().reduce(0, combine: +)

Swift Variable Argument [duplicate]

This question already has answers here:
Passing lists from one function to another in Swift
(2 answers)
Passing an array to a function with variable number of args in Swift
(7 answers)
Closed 8 years ago.
In "The Swift Programming Language", Functions and Closures, there is a sample code to calculate the total as below:
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
As part of the following experiment, I tried the following function to calculate the average
func averageOf(numbers : Int...) -> Int {
var argument:Array = numbers
var average = sumOf(argument) / numbers.count
return average
}
However, I get the following error
[Int] is not convertible to Int
I have also tried the following line with no success
var average = sumOf(numbers) / numbers.count
Any idea whats going on underneath? Why is sumOf parameter is treating it as Int instead of an array when the book clearly states that
“Functions can also take a variable number of arguments, collecting
them into an array.”
It seems to me you function is ok if you try to call it properly.
sumOf(25,23,43,23)
But if you would like to call array use this code :
import UIKit
var someInts = [Int]()
someInts.append(8)
someInts.append(6)
someInts.append(6)
someInts.append(3)
someInts.append(5)
func sumOf(numbers: [Int]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf(someInts)
The main problem that in function you declare parameter not as array but like undefined amount of the integers
Just change definition of method To
func sumOf(numbers: [Int]) -> Int
Instead Of
func sumOf(numbers: Int...) -> Int
Because you are passing array as an argument to func sumOf function, which is not expected as its define.

Swift Closure parameters, manipulate by position

How to manipulate the closure parameters by their position in Swift.
I've tried in the following way, But, couldn't get the idea behind it, from the documentation.
var additionClosure = { (a : Int , b : Int )-> Int in
return ($0 + $1)
}
var a = 10
var b = 20
println("additionClosure \(additionClosure(a,b))")
Any help would be appreciated..... Well, Thanks in advance.
`The numbered argument format is used for when you don't want to create a named closure.
Example:
import Foundation
func add(a : Int, b : Int) -> Int {
return a + b
}
func test(a : (Int, Int) -> Int) {
println("result: \(a(10,20))")
}
test(add) // Calling test with a named closure
test({$0 + $1}) // Calling test with an anonymous closure
In the first case you define add with two parameters, and give them names a and b. In the second case, you don't even define the name of the closure, just the required functionality using $0 and $1

Resources