Passing an array to a function with variable number of args in Swift
Splatting is not in the language yet, as confirmed by the devs. Workaround for now is to use an overload or wait if you cannot add overloads.
How to pass an array to a function which is variadic in Swift?
Provided the variadic function returns the same type as its parameter (like your 'foo' example), then you can define apply like this :
func apply<T>(_ f:(T ...) -> T, with elements:[T]) -> T {
var elements = elements
if elements.count == 0 {
return f()
}
if elements.count == 1 {
return f(elements[0])
}
var result:T = f(elements.removeFirst(), elements.removeFirst())
result = elements.reduce(result, {f($0, $1)} )
return result
}
then to call it :
func foo(_ n: String ...) -> String {
return n.joined(separator: ", ")
}
func sum(_ numbers:Int ...) -> Int {
return numbers.reduce(0, +)
}
let arrInt = [3, 5, 10]
apply(sum, with: arrInt) // 18
let arrString = ["apple", "peer", "banana"]
apply(foo, with: arrString) // "apple, peer, banana"
How can I pass an array as parameter without using Brackets in Swift?
you can achieve this via Variadic functions this allows you to input parameter as comma separated values. just put 3 dots at the the end of parameter type
func customFunction(values: String...) {
for value in values {
print(value)
}
}
function call
customFunction(values: "1", "2", "3")
Passing in variable number of args from one function to another in Swift
sumOf and averageOf both take a variadic paramter of Int, which is not the same as an Array of Int. The variadic paramter is converted into an Array, though which is what numbers it, but then you aren't able to call sumOf on numbers.
You can fix this by making a sumOf function that takes a variadic parameter and one that takes an arrary like this:
func sumOf(numbers: Int...) -> Int {
return sumOf(numbers)
}
func sumOf(numbers: Int[]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
Swift function with args... pass to another function with args
Similar as in (Objective-)C, you cannot pass a variable argument list
directly to another function. You have to create a CVaListPointer
(the Swift equivalent of va_list
in C) and call a function which
takes a CVaListPointer
parameter.
So this could be what you are looking for:
extension String {
func getLocalizeWithParams(args : CVarArgType...) -> String {
return withVaList(args) {
NSString(format: self, locale: NSLocale.currentLocale(), arguments: $0)
} as String
}
}
withVaList()
creates a CVaListPointer
from the given argument list
and calls the closure with this pointer as argument.
Example (from the NSString
documentation):
let msg = "%@: %f\n".getLocalizeWithParams("Cost", 1234.56)
print(msg)
Output for US locale:
Cost: 1,234.560000
Output for German locale:
Cost: 1.234,560000
Update: As of Swift 3/4/5 one can pass the arguments to
String(format: String, locale: Locale?, arguments: [CVarArg])
directly:
extension String {
func getLocalizeWithParams(_ args : CVarArg...) -> String {
return String(format: self, locale: .current, arguments: args)
}
}
passing unknown number of arguments in a function
Swift Variadic Parameters
accepts zero or more parameters of a specified type. Syntax of variadic parameters is, insert three period characters (...)
after the parameter’s type name.
func anyNumberOfTextField(_ textField: UITextField...) {
}
Now you can pass any number of textField.
anyNumberField(UITextField(),UITextField(), UITextField(), UITextField())
Note: A function may have at most one variadic parameter.
For more info check this Swift Functions
There is another way you can do that is called Array Parameter
. There are some pros and cons of these two methods. You will find the difference here link.
How to loop through array of dynamic size and pass properties as arguments in variadic function?
I may be misunderstanding the question. I don't know if you want a general way to do this, but NSExpression
has an init that takes an array: https://developer.apple.com/documentation/foundation/nsexpression/1413484-init
So you could do something like:
let defaultShapeExpression = NSExpression(forConstantValue: "grayMarker")
// Either do clean array or add your initial arguments
var expressionArguments = [Any]()
var format = "MGL_MATCH(type, "
for pinType in self.pinTypes {
format += "'\(pinType.id ?? "")', %@, "
expressionArguments.append(NSExpression(pinType.iconImageProperty))
}
format += "%@)"
expressionArguments.append(defaultShapeExpression)
let expression = NSExpression(format: format, argumentArray: expressionArguments)
Hopefully this helps. I'm sitting at my desktop, so I can't really test anything myself.
Related Topics
Rounding a Double Value to X Number of Decimal Places in Swift
How to Resolve: 'Keywindow' Was Deprecated in iOS 13.0
Swift 5.0: 'Withunsafebytes' Is Deprecated: Use 'Withunsafebytes≪R≫(...)
How to Round a Double to the Nearest Int in Swift
How to Encode Enum Using Nscoder in Swift
Failing Cast in Swift from Any? to Protocol
Ios 11 Custom Navbar Goes Under Status Bar
Swift Beta 6 - Confusing Linker Error Message
How to Use Userdefaults With Swiftui
How to Convert Double to Int in Swift
How to Run a Terminal Command in a Swift Script? (E.G. Xcodebuild)
Append Text or Data to Text File in Swift
Real Time Nstask Output to Nstextview With Swift
Saving Picked Image to Coredata
Use Binding≪Int≫ With a Textfield Swiftui