How to Deal with Default Initializer when variable are not initialized Using Struct - ios

I'm using swift struct and trying to use its default initializer when my struct variables are not initialize, I try both non-optional and optional variables but in its only showing "memberwise Initializer".
below is example with optional variables
struct myFirstStruct {
var value1:String?
var value2:String?
}
below is example with non-optional variables
struct myFirstStruct {
var value1:String
var value2:String
}
and it only gives
myFirstStruct(value1: <#String?#>, value2: <#String?#>)
and i want to use myFirstStruct()
help me. :)

Xcode is only showing you the 'member-wise' initialiser, but it's perfectly valid to use myFirstStruct(), passing no arguments, because all your variables have default values.
struct myFirstStruct {
var value1:String?
var value2:String = "InitialString"
}
let s1 = myFirstStruct()
// value1 = nil, value2 = "InitialString"
let s2 = myFirstStruct(value1: "Hello", value2: "World")
// value1 = "Hello", value2 = "World"

Need to set default value.
struct myFirstStruct {
var value1:String? = nil
var value2:String? = nil
}
let object = myFirstStruct()

Related

Access Value in Dictionary using Random Number

I am trying to access the value from a dictionary using a random number, but I am lost, can someone please guide?
Here is what I have:
var themes = ["Halloween": "πŸ˜ˆπŸ’€πŸ€‘πŸ‘»πŸ€–πŸ‘½", "Sports": "πŸ‰πŸ“β›³οΈβš½οΈπŸŽ³πŸŽ±" , "Faces": "πŸ˜€πŸ˜πŸ˜¨πŸ€—πŸ˜€πŸ€€", "Animal": "πŸ¦“πŸ˜ΌπŸ˜ΊπŸ˜ΏπŸ™€πŸ™ˆ"]
// This Does not work for some reason?
lazy var themeRandomNumber = themes.count.arc4random
lazy var currentTheme = themes[themeRandomNumber]
//Cannot subscript a value of type[String : String]' with an index of type 'Int'
This makes sense since, I am trying to access the key using an Int when it is obviously a String, but not sure how to proceed?
lazy var currentEmoji = themes[currentTheme]
extension Int{
var arc4random: Int{
if self > 0 {
return Int(arc4random_uniform(UInt32(self)))
} else if self < 0 {
return -Int(arc4random_uniform(UInt32(abs(self))))
} else {
return 0
}
}
}
Just replace
lazy var currentEmoji = themes[currentTheme]
with
var currentTheme = themes.randomElement()
print(currentTheme?.value) //Optional("πŸ‰πŸ“β›³οΈβš½οΈπŸŽ³πŸŽ±")
print(currentTheme?.key) //Optional("Sports")
Here randomElement is new property which you can use to get random element.
Because you're not accessing the key of your dictionary, you need to select "Halloween", "Sports", "Faces" or "Animal" - your themes dict's keys.
You can use some custom mapping method with Int.random(in: 0...3) or a Keys enum conforming to CaseIterable, and then you need to select a random character (emoji) in the String for your given Key (via a random number in the range 0..<string.length).
EDIT
With Swift 4.2+ (Xcode 10) you can use randomElement():
var themes = ["Halloween": "πŸ˜ˆπŸ’€πŸ€‘πŸ‘»πŸ€–πŸ‘½", "Sports": "πŸ‰πŸ“β›³οΈβš½οΈπŸŽ³πŸŽ±" , "Faces": "πŸ˜€πŸ˜πŸ˜¨πŸ€—πŸ˜€πŸ€€", "Animal": "πŸ¦“πŸ˜ΌπŸ˜ΊπŸ˜ΏπŸ™€πŸ™ˆ"]
var randomEmoji = themes.randomElement()?.value.randomElement()

Swift Struct unable to set array elements above 0

I have following Swift struct:
struct MainStruct : Decodable{
var array : [InternalArray]?
}
struct InternalArray : Decodable{
var firstName : String?
var lastName : String?
var Number : Int?
}
And this is how I'm using it:
var testing: MainStruct? = MainStruct()
testing?.array = []
testing?.array!.append(InternalArray())
testing?.array![0].firstName = "TEST"
testing?.array![1].firstName = "TEST 1" - error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION
It seems to work fine when I'm setting array element [0] but when I try to set element [1] I get an error. Maybe somebody know what is wrong with my implementation ?
The problem is you only have 1 item (index 0).
Let's unpack this, first we unwrap your option MainStruct in the testing variable, and unwrap the optional array:
if let unwrappedTestingMainStruct = testing,
let unwrappedArray = unwrappedTestingMainStruct.array {
unwrappedArray.count // = 1
}
You then try to access testing?.array![1] which would be the second item in the array… which doesn't exist.
If you just had the line:
testing?.array![1]
you would see the same error

Check if an element is present in 3D array Swift

I have an array which gets instantiated in viewDidLoad like var bookingsArray : [[String]] = []
I am adding elements to it in this way:
var configuration: [String] = []
configuration.append(textfieldFacility.text!)
configuration.append((pickSlotTF.text?.components(separatedBy: " ")[0])!)
configuration.append((pickSlotTF.text?.components(separatedBy: " ")[1])!)
bookingsArray.append(configuration as [String])
bookingsArray looks like :
[["A", "20-08-2017", "14:00"], ["B", "20-08-2017", "14:00"]]
While adding new elements to bookingsArray, I want to check if the new element is already present in the array. How do I do it in this case of multi-dimensional array?
First of all, if you want unique objects use a Set.
If this is not possible I highly recommend to use a custom struct which can conform to Equatable rather than a nested array , for example
struct Booking : Equatable {
let facilty : String
let date : String
let time : String
static func ==(lhs : Booking, rhs : Booking) -> Bool {
return lhs.facilty == rhs.facilty && lhs.date == rhs.date && lhs.time == rhs.time
}
}
Then declare the array as
var bookingsArray = [Booking]()
and create an object with
let dateArray = pickSlotTF.text!.components(separatedBy: " ")
let configuration = Booking(facility: textfieldFacility.text!,
date: dateArray[0],
time = dateArray[1])
bookingsArray.append(configuration)
The huge benefit is that you can easily check
if bookingsArray.contains(item)
You can simply search for it with contains().
var configuration: [String] = []
configuration.append(textfieldFacility.text!)
configuration.append((pickSlotTF.text?.components(separatedBy: " ")[0])!)
configuration.append((pickSlotTF.text?.components(separatedBy: " ")[1])!)
if !bookingsArray.contains(where: {$0 == configuration}) {
bookingsArray.append(configuration)
}

Find Object with Property in Array

is there a possibility to get an object from an array with an specific property? Or do i need to loop trough all objects in my array and check if an property is the specific i was looking for?
edit: Thanks for given me into the correct direction, but i have a problem to convert this.
// edit again: A ok, and if there is only one specific result? Is this also a possible method do to that?
let imageUUID = sender.imageUUID
let questionImageObjects = self.formImages[currentSelectedQuestion.qIndex] as [Images]!
// this is working
//var imageObject:Images!
/*
for (index, image) in enumerate(questionImageObjects) {
if(image.imageUUID == imageUUID) {
imageObject = image
}
}
*/
// this is not working - NSArray is not a subtype of Images- so what if there is only 1 possible result?
var imageObject = questionImageObjects.filter( { return $0.imageUUID == imageUUID } )
// this is not working - NSArray is not a subtype of Images- so what if there is only 1 possible result?
You have no way to prove at compile-time that there is only one possible result on an array. What you're actually asking for is the first matching result. The easiest (though not the fastest) is to just take the first element of the result of filter:
let imageObject = questionImageObjects.filter{ $0.imageUUID == imageUUID }.first
imageObject will now be an optional of course, since it's possible that nothing matches.
If searching the whole array is time consuming, of course you can easily create a firstMatching function that will return the (optional) first element matching the closure, but for short arrays this is fine and simple.
As charles notes, in Swift 3 this is built in:
questionImageObjects.first(where: { $0.imageUUID == imageUUID })
Edit 2016-05-05: Swift 3 will include first(where:).
In Swift 2, you can use indexOf to find the index of the first array element that matches a predicate.
let index = questionImageObjects.indexOf({$0.imageUUID == imageUUID})
This is bit faster compared to filter since it will stop after the first match. (Alternatively, you could use a lazy sequence.)
However, it's a bit annoying that you can only get the index and not the object itself. I use the following extension for convenience:
extension CollectionType {
func find(#noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
return try indexOf(predicate).map({self[$0]})
}
}
Then the following works:
questionImageObjects.find({$0.imageUUID == imageUUID})
Yes, you can use the filter method which takes a closure where you can set your logical expression.
Example:
struct User {
var firstName: String?
var lastName: String?
}
let users = [User(firstName: "John", lastName: "Doe"), User(firstName: "Bill", lastName: "Clinton"), User(firstName: "John", lastName: "Travolta")];
let johns = users.filter( { return $0.firstName == "John" } )
Note that filter returns an array containing all items satisfying the logical expression.
More info in the Library Reference
Here is a working example in Swift 5
class Point{
var x:Int
var y:Int
init(x:Int, y:Int){
self.x = x
self.y = y
}
}
var p1 = Point(x:1, y:2)
var p2 = Point(x:2, y:3)
var p3 = Point(x:1, y:4)
var points = [p1, p2, p3]
// Find the first object with given property
// In this case, firstMatchingPoint becomes p1
let firstMatchingPoint = points.first{$0.x == 1}
// Find all objects with given property
// In this case, allMatchingPoints becomes [p1, p3]
let allMatchingPoints = points.filter{$0.x == 1}
Reference:
Trailing Closure
Here is other way to fetch particular object by using object property to search an object in array.
if arrayTicketsListing.contains({ $0.status_id == "2" }) {
let ticketStatusObj: TicketsStatusList = arrayTicketsListing[arrayTicketsListing.indexOf({ $0.status_id == "2" })!]
print(ticketStatusObj.status_name)
}
Whereas, my arrayTicketsListing is [TicketsStatusList] contains objects of TicketsStatusList class.
// TicketsStatusList class
class TicketsStatusList {
internal var status_id: String
internal var status_name: String
init(){
status_id = ""
status_name = ""
}
}

Swift Dictionary with Array Values

If I declare a class property as:
var list = Dictionary<String, StructType[]>()
and then try to add a value from within a class method with:
var structType = StructType()
list[ "A" ] = [ structType ]
I get a runtime EXC_BAD_INSTRUCTION error. However, if I declare the dictionary within the class method and add a value there is no error.
It has something to do with the dictionary having values which are arrays. If I change the declaration to something simpler, like:
var list = Dictionary<String, String>()
then within the class method:
list["A"] = "some string"
works without any issues.
Any ideas?
UPDATE:
I've also tried declaring:
var list = Dictionary<String, String[]>()
and there is no issue referencing the list within a class method.
list[ "A" ] = [ "String1", String2" ]
Also the class declaration:
var list = Dictionary<String, SomeStruct>()
can be referenced within a class method.
UPDATE 2:
The struct is defined as:
struct Firm {
var name = ""
}
If you create your list and class in the following way it should work fine:
struct StructType {
var myInt = 0;
}
class MyClass {
var list = Dictionary<String, StructType[]>()
func myFunc () {
var structType = StructType()
list[ "A" ] = [ structType ]
}
}
var a = MyClass()
a.myFunc()
The following code appears to work for me in a playground.
struct StructType {
}
var list = [String:[StructType]]()
var structType = StructType()
list["A"] = [structType]

Resources