How to append a tuple to an array object in Swift

2019-01-15 13:46发布

问题:

This question already has an answer here:

  • Array of tuples in Swift 3 answers

I searched google, but i cant find a way to append new element to array object in Swift. The error code "Missing arguments fot parameter "name" in call" is come up. My code is followed.

var arrayObj: [(id: Int, name: String)] = []
var idInt: Int = 1
var nameString: String = "hoge"
arrayObj.append((        // ----> "Missing arguments fot parameter "name" in call"
    id: idInt,
    name: nameString
))

if you know any solution, I'd be very glad. Thanks.

回答1:

Just assign the tuple to a temp variable:

let tuple = (        
    id: idInt,
    name: nameString
)

arrayObj.append(tuple)

Not sure why it doesn't work that way - just checked on a function, like this:

var array:  [(param1: Int, param2: String)] = []

func test(x: (param1: Int, param2: String)) {
    println(x)
}

test((param1: 2, param2: "Test"))
array.append((param1: 2, param2: "Test"))

Result: the function works, the array method doesn't.

Update: Tried this code in a playground:

struct Test<T> {
    func doSomething(param: T) {
        println(param)
    }
}

var test = Test<(param1: Int, param2: String)>()
let tuple = (param1: 2, param2: "Test")
test.doSomething(tuple)
test.doSomething((param1: 2, param2: "Test"))

Result: it works when passing the tuple variable to doSomething - using the literal tuple instead doesn't, although the compiler message is different:

'((param1: Int, param2: String)) ->()' does not have a member named 'doSomething'

Apparently passing a literal tuple to a method of a generic class (where the tuple is the generic type) is not correctly handled by the compiler.

Update #2: I repeated the test on a non-generic class, but using a generic method, and in this case it worked:

struct Test {
    func doSomething<T>(param: T) {
        println(param)
    }
}

var test = Test()
let tuple = (param1: 2, param2: "Test")
test.doSomething(tuple)
test.doSomething((param1: 2, param2: "Test"))

So it's definitely a problem related to generic classes only.



回答2:

More fun workarounds:

arrayObj += [(id: idInt, name: nameString)]

and

arrayObj.append([(id: idInt, name: nameString)][0])

Curiously, this works if you use a typealias:

typealias MyData = (id: Int, name: String)

var arrayObj: [MyData] = []
var idInt: Int = 1
var nameString: String = "hoge"

arrayObj.append((id: idInt, name: nameString))

EDIT:

One more workaround:

arrayObj.insert((id: idInt, name: nameString), atIndex:index)


回答3:

I just want to clear some things up:

If you have an array of tuples with named elements, just like in the answer, you can use the syntax described below to add elements to the array:

arrayObj.append(id: 1, name: "TestName")

If you have an array of tuples with not named elements, like this:

var arrayObj: [(Int, String)] = []

use this:

arrayObj.append(1, "TestName")

If you created a typealias for you tuple, you can add elements to the list with the tuple syntax:

typealias MyTuple = (Int, String)
var arrayObj: [MyTuple] = []

arrayObj.append((1, "TestName"))


标签: swift xcode6