How to find the index of a tuple element from an tuple array? iOS, Swift
Tuples can be compared for equality (as of Swift 2.2/Xcode 7.3.1), but
they do not conform to the Equatable
protocol. Therefore you have
to use the predicate-based variant of indexOf
to locate a tuple
in an array. Example:
let valueArray = [("a", "b"), ("c", "d")]
let tuple = ("c", "d")
if let index = valueArray.indexOf({ $0 == tuple }) {
print("found at index", index)
}
In Swift 4 the method has been renamed to firstIndex(where:)
:
if let index = valueArray.firstIndex(where: { $0 == tuple }) {
print("found at index", index)
}
Is it possible to find the index of an tuple in an array?
use index with where clause, here a sample for a tuple with 2 members
let index = array.index {
$0 == element.0 && $1 == element.1
}
Swift - Search and Replace value in Tuple
You can search an array of tuples using firstIndex(where:)
to find the index of the first element to match your condition. In your case, you are looking to match a specific id
, so you would use a closure such as { $0.id == "2" }
.
Once you find that index, you can use it to update the tuple inside of the array.
Example:
var info: [(id: String, name: String, years: Int, city: String)] = [
("1", "Fred", 35, "Bedrock"),
("2", "Wilma", 32, "Bedrock")
]
if let idx = info.firstIndex(where: { $0.id == "2" }) {
info[idx].city = "Boulder"
}
print(info)
Output
[(id: "1", name: "Fred", years: 35, city: "Bedrock"),
(id: "2", name: "Wilma", years: 32, city: "Boulder")]
Use a struct
instead of a tuple
That said, you should really use a struct
here to contain your values. Tuples in Swift are really meant for temporary use (such as returning multiple values from a function), so defining a struct
to hold your values is preferred:
struct Record {
var id: String
var name: String
var years: Int
var city: String
}
var info: [Record] = [
.init(id: "1", name: "Fred", years: 35, city: "Bedrock"),
.init(id: "2", name: "Wilma", years: 32, city: "Bedrock")
]
The searching code would remain the same.
Can I retrieve an item from a tuple in the same way as indexing an item from an array in a for loop?
Check out this link for the inspiration to this answer. First add this function somewhere accessible in your code:
func iterate<Tuple>(_ tuple:Tuple, body:(_ label:String?,_ value:Any)->Void) {
for child in Mirror(reflecting: tuple).children {
body(child.label, child.value)
}
}
Then use this updated version of your code:
if objectType === UIButton.self {
if xOriginCgFloat.2 != nil || yOriginCgFloat.2 != nil || width.2 != nil || height.2 != nil {
var buttonOneData:[CGFloat] = [CGFloat]()
var buttonTwoData:[CGFloat] = [CGFloat]()
var buttonThreeData:[CGFloat] = [CGFloat]()
var buttonsData:[[CGFloat]] = [buttonOneData,buttonTwoData,buttonThreeData]
var tuples = [xOriginCgFloat,yOriginCgFloat,width,height]
for tuple in tuples {
iterate(tuple) {
var indexStr = $0! //index = .0,.1,.2, etc
indexStr.remove(at:indexStr.startIndex) //remove the . from .0,.1,.2,etc.
let index = Int(indexStr)
buttonsData[index].append(CGFloat($1 as! Int)) //$1 = the value of tuple.0, tuple.1, tuple.2, etc.
}
}
for (index,buttonData) in buttonsData.enumerated() {
var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: buttonData[index], y: buttonData[index]), size: CGSize.init(width: buttonData[index], height: buttonData[index])))
buttonArray.append(button)
}
} else {
fatalError("Each tuple for a button object must have exactly three values.")
}
}
It is very convoluted and I'm honestly not a big fan of it, but if you need to use tuples, then this will (probably) work for you. I basically used the iterate function from the list at the top of this answer to go through your tuples and add them to arrays that separated the data from the tuples into an array of button data, which I then made an array so you can iterate through that and make the actual buttons.
Accessing an array of tuples Swift 4
You should do something like this:
class eventCell: UICollectionViewCell {
@IBOutlet private weak var eventTitle: UILabel!
@IBOutlet private weak var descriptionLabel:UILabel!
@IBOutlet private weak var eventImage: UIImageView!
typealias Event = (title:String, location:String, lat:CLLocationDegrees, long:CLLocationDegrees)
var eventArray = [Event]()
override func prepareForReuse() {
eventImage.image = nil
}
func lool() {
var event = Event(title: "a", location:"b", lat:5, long:4)
eventArray.append(event)
eventTitle.text = eventArray[0].title
}
}
Swift: Get an element from a tuple
According to the documentation (scroll down to Tuples), there are three ways to do it.
Given
var answer: (number: Int, good: Bool) = (100, true)
Method 1
Put the element variable name within a tuple.
let (firstElement, _) = answer
let (_, secondElement) = answer
or
let (firstElement, secondElement) = answer
Method 2
Use the index.
let firstElement = answer.0
let secondElement = answer.1
Method 3
Use the names. This only works, of course, if the elements were named in the Tuple declaration.
let firstElement = answer.number
let secondElement = answer.good
How to get keys from Array of tuple in Swift
Maybe you can transform it to an array of tuple:
let personalInfoDict = screenConfigResponse?.screenConfiguration?.personalInformation
let personalPairs = personalInfoDict
.reduce(into: [(String, Int)]()) { $0.append(($1.key, $1.value)) }
.sorted(by: { $0.0 < $1.0 })
if let pArray = personalPairs, pArray.count > 0 {
for obj in pArray {
personalInformationArray.append(obj.0)
}
}
Now you have a [(String, Int)]
ordered array
Related Topics
Adding a Target to a Button Programmatically Throws an Error "Unrecognized Selector Sent to Class"
Impelementation of Rtcdatachannel of Webrtc in iOS
Which Passes How to Access in Apple Wallet
Aes 128 Message Decryption -- Swift, iOS
Swift: Triggering Tableviewcell to Lead to a Link in a Uiwebview in Another Viewcontroller
Vnfaceobservation Boundingbox Not Scaling in Portrait Mode
Binary Operator + Cannot Be Applied to Operands of Type Cgfloat Int
How to Change Uinavigationbar Per View Controller
How to Get Account Name from Contact Framework
My Reachability Notifier Is Only Able to Be Called Once
Pausing Timer When App Is in Background State Swift
Required Initializers for a Subclass of Uiviewcontroller
How to Add the Same Background Image to All Views in My iOS App Using Swift
Pure Swiftui Login, Signup, Register Flow, Is It Possible
Format String with Variadic Arguments
How to Change Uitextfield Color in Searchcontroller
Could Not Cast Value of Type 'Nsnull' (0X10Aa1B600) to 'Nsstring' (0X10B4Dab48)