可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to add a tuple (e.g., 2-item tuple) to an array.
var myStringArray: (String,Int)[]? = nil
myStringArray += ("One", 1)
What I'm getting is:
Could not find an overload for '+=' that accepts the supplied
arguments
Hint: I tried to do an overload of the '+=' per reference book:
@assignment func += (inout left: (String,Int)[], right: (String,Int)[]) {
left = (left:String+right:String, left:Int+right+Int)
}
...but haven't got it right.
Any ideas? ...solution?
回答1:
Since this is still the top answer on google for adding tuples to an array, its worth noting that things have changed slightly in the latest release. namely:
when declaring/instantiating arrays; the type is now nested within the braces:
var stuff:[(name: String, value: Int)] = []
the compound assignment operator, +=
, is now used for concatenating arrays; if adding a single item, it needs to be nested in an array:
stuff += [(name: "test 1", value: 1)]
it also worth noting that when using append()
on an array containing named tuples, you can provide each property of the tuple you're adding as an argument to append()
:
stuff.append((name: "test 2", value: 2))
回答2:
You have two issues. First problem, you're not creating an "array of tuples", you're creating an "optional array of tuples". To fix that, change this line:
var myStringArray: (String,Int)[]? = nil
to:
var myStringArray: (String,Int)[]
Second, you're creating a variable, but not giving it a value. You have to create a new array and assign it to the variable. To fix that, add this line after the first one:
myStringArray = []
...or you can just change the first line to this:
var myStringArray: (String,Int)[] = []
After that, this line works fine and you don't have to worry about overloading operators or other craziness. You're done!
myStringArray += ("One", 1)
Here's the complete solution. A whopping two lines and one wasn't even changed:
var myStringArray: (String,Int)[] = []
myStringArray += ("One", 1)
回答3:
If you remove the optional, it works fine, otherwise you'll have to do this:
var myStringArray: (String,Int)[]? = nil
if !myStringArray {
myStringArray = []
}
var array = myStringArray!
array += ("One", 1)
myStringArray = array
You can never append an empty array, so you'll have to initialize it at some point. You'll see in the overload operator below that we sort of lazy load it to make sure that it is never nil.
You could condense this into a '+=' operator:
@assignment func += (inout left: Array<(String, Int)>?, right: (String, Int)) {
if !left {
left = []
}
var array = left!
array.append(right.0, right.1)
left = array
}
Then call:
var myStringArray: (String,Int)[]? = nil
myStringArray += ("one", 1)
回答4:
I've ended up here multiple times due to this issue. Still not as easy as i'd like with appending onto an array of tuples. Here is an example of how I do it now.
Set an alias for the Tuple - key point
typealias RegionDetail = (regionName:String, constraintDetails:[String:String]?)
Empty array
var allRegionDetails = [RegionDetail]()
Easy to add now
var newRegion = RegionDetail(newRegionName, constraints)
allRegionDetails.append(newRegion)
var anotherNewRegion = RegionDetail("Empty Thing", nil)
allRegionDetails.append(anotherNewRegion)
回答5:
Swift 4 solution:
// init empty tuple array
var myTupleArray: [(String, Int)] = []
// append a value
myTupleArray.append(("One", 1))
回答6:
Note:
It's not work anymore
if you do:
array += tuple
you will get error
what you need is :
array += [tuple]
I think apple change to this representation because it's more logical
回答7:
@assignment func += (inout left: Array<(String, Int)>?, right: (String, Int)) {
if !left {
left = []
}
if left {
var array = left!
array.append(right.0, right.1)
left = array
}
}
var myStringArray: (String,Int)[]? = nil
myStringArray += ("x",1)
回答8:
Thanks to comments:
import UIKit
@assignment func += (inout left: Array<(String, Int)>?, right: (String, Int)) {
if !left {
left = []
}
if left {
var array = left!
array.append(right.0, right.1)
left = array
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
println("interestingNumbers: \(interestingNumbers)\n")
var largest = 0
var myStringArray: (String,Int)[]? = nil
myStringArray += ("One", 1)
var x = 0
for (kind, numbers) in interestingNumbers {
println(kind)
for number in numbers {
if number > largest {
largest = number
}
x++
println("\(x)) Number: \(number)")
myStringArray += (kind,number)
} // end Number
} // end Kind
println("myStringArray: \(myStringArray)")
}
}
The Output:
interestingNumbers: [Square: [1, 4, 9, 16, 25], Prime: [2, 3, 5, 7,
11, 13], Fibonacci: [1, 1, 2, 3, 5, 8]]
Square
1) Number: 1
2) Number: 4
3) Number: 9
4)
Number: 16
5) Number: 25
Prime
6) Number: 2
7)
Number: 3
8) Number: 5
9) Number: 7
10) Number: 11
11) Number: 13
Fibonacci
12) Number: 1
13) Number:
1
14) Number: 2
15) Number: 3
16) Number: 5
17)
Number: 8
Array of tupules:
myStringArray: [(One, 1), (Square, 1), (Square, 4), (Square, 9),
(Square, 16), (Square, 25), (Prime, 2), (Prime, 3), (Prime, 5),
(Prime, 7), (Prime, 11), (Prime, 13), (Fibonacci, 1), (Fibonacci, 1),
(Fibonacci, 2), (Fibonacci, 3), (Fibonacci, 5), (Fibonacci, 8)]