lets say I have
struct Two {var names: String }
then I create two instances of this struct
var one = Two(names: "one")
var two = Two(names: "two")
Would I be able to create an array that specifically holds struct instances, something like?
var options:Two = [[one],[two]]
If not, what would be the advisable path to complete this logic?
Yes, you can. The type you're looking for is [[Two]], which is a 2D array of Two, or an array of arrays of Twos. Usage:
struct Two {
var names: String
}
var one = Two(names: "one")
var two = Two(names: "two")
var options: [[Two]] = [[one],[two]]
Related
and good job , well basically i have array like this :
let imageArray = [ ["image0"] , ["image11","image12"] , ["image2"], ["image31","image32","image33"] ]
In this point i want to put for example first item of each nested array into a new array like this :
var newArray = ["image0","image11","image2","image31"]
And also i want to have a condition for example if "image31" clicked we have a new page that show ervery images of that first array show us, like ["image31", "image32", "image33"]
So could you tell any idea how can implement like this?
You can try
let res = imageArray.map { $0.first! }
When clicked use the index to access other elements , say from above index 3 image is clicked then use
let resImages = imageArray[clickedIndex]
Edit:
let arr = ["images/product/2021-05-02T09-47-17.699Z-download (2).jpg"]
let res = arr.map { $0[$0.range(of: "images/product/")!.upperBound...] }
print(res)
Using simple data structures (like arrays) to model complex data is rarely the best approach.
In this case I would create a struct ImageList and then create an array of this struct
struct ImageList {
let images: [String]
var firstImage: String? {
return self.images.first
}
}
You can use map to create the array from your current source, if required
imageListArray = imageArray.map { ImageList(images:$0) }
Now you can have an index that is associated with an ImageList struct - imageListArray[i].firstImage! is the value you want for your list and iageListArray[i].images is the array you want for your second requirement.
In my app I have two struct arrays and I want to remove common items from one of them. My struct:
struct PeopleSelectItem {
var name = ""
var id = ""
var added = false
}
My arrays:
var people : [PeopleSelectItem] = []
var selectedPeople : [PeopleSelectItem] = []
I want to remove items from people array if they exist (compare by id) on selectedPeople array.
I tried several array filtering and converting to set but none of them worked. What can I do here?
Thanks!
Get an array of all ids in selectedPeople
let selectedPeopleIDs = selectedPeople.map(\.id)
Filter the items whose id is not in the array
let filteredPeople = people.filter { !selectedPeopleIDs.contains($0.id) }
If you know that people equal each other if the id is the same then you can conform your struct to the Equatable protocol and you can use the array filter method.
struct PeopleSelectItem : Equatable {
var name = ""
var id = ""
var added = false
}
func ==(lhs: PeopleSelectItem, rhs: PeopleSelectItem) -> Bool {
return lhs.id == rhs.id
}
func filterPeople() {
//swift 2, 3:
people = people.filter{!selectedPeople.contains($0)}
//swift older versions:
people = people.filter{!contains(selectedPeople, $0)}
}
If people might have a significant amount of entries, performance should be considered. So, instead of searching with an n^2 algorithm, you should make use of Swifts dictionary and the corresponding hash-search to find items.
If Id is unique for people then I would store them in a dictionary like:
var peopleDict: [String:PeopleSelectItem] = [:]()
You can easily convert from the array you have to this dictionary:
people.foreach {peopleDict[$0.id] = $0}
With this dictionary it's very easy to delete single entries:
selectedPeople.foreach {peopleDict.remove($0.id)}
Optionally to switch back to an array for people you just say:
let filteredPeople = peopleDict.values as [PeopleSelectItem]
Remarks
I assumed, that selectedPeople is smaller then the base of all people. If this is not the case, you should pu selectedPeople in a dictionary.
did I say I like this Spark like api? I think I do so.
I just wrote that code from top of my mind. If it is not completely syntactically correct let me know and I correct it.
I have two separate arrays that I want to import into a dictionary. Order is extremely important because both arrays must match in index
struct MyVariables {
static var users:NSArray!
static var img:NSArray!
}
var data = SearchVC.getData()
MyVariables.users = data.users; //array 1 (key)
MyVariables.img = data.img; //array 2
// Goal is to insert these arrays into a dictionary while maintaing the matching indexes on both arrays
// Dictonary (MyVariables.img, key: MyVariables.users)
A Dictionary does not have a particular order. However, if both arrays have the same length, it is quite easy to iterate over them together:
var dictionary = [NSString: AnyObject]()
for var index = 0; index < data.users.count; index++ {
let img = data.img as! NSString
dictionary[img] = data.users[index]
}
Or, as #robertvojta suggested, use the zip() method:
var dictionary = [NSString: AnyObject]()
for (user, image) in zip(data.users, data.img) {
let img = image as! NSString
dictionary[img] = user
}
The key in a dictionary in swift must be hashable. i.e., not AnyObject.
Assuming you can replace some of your untyped Swift arrays, or cast them like so:
struct MyVariables {
var users:Array<AnyObject>
var img:Array<String>
}
then you can iterate through 1 array using a preferred Swift method and access the second using indexing:
var dictionary = Dictionary<String, AnyObject>()
for (index, element) in enumerate(MyVariables.img) {
dictionary[element] = MyVariables.users[index]
}
Use for loop for travels the array in that as per index access keys and values respective array and add it in dictionary. Its so simple so you can achive your goal using it.
I hope it will help you!
I want to create an empty array that will contain strings.
What are differences between the following two approaches and which one is better to use?
var arr:[String] = []
// versus
var arr = [String]()
AFAIU, the first approach is essentially equivalent to Array<String>(arrayLiteral: ...) with empty set of literals. The second one is just Array<String>(). Despite same end result, the latter should be more preferable just because it takes less to execute. You can explore this for yourself by debugging both options with stepping into instructions.
The first one, var arr:[String] = [] is usually used for adding values upon initialisation. You could create an empty array like this, but usually you would do the second one to create the empty array: var are = [String]().
Either one is acceptable, but usually you would use the first for adding values on initialisation, just like you would with normal variables: you would normally write something like this:
var exampleVariable:String = "Example String"
and to compare the second, it would be like writing:
var exampleVariable = String()
Simply, you are adding the square brackets to show you are making an array.
I'm answering very late this question because it's missing, in my opinion they key words Type Annotation & Type Inference.
var arr: [String] = []
You are declaring a variable arr of type [String] (array of String), with the : [String] part. It's the Type Annotation
Then you assign its value with [], ie create an empty array, and since the compiler knows it's an array of String, it will create an empty array of string.
var arr = [String]()
You are creating a variable arr without specifying its type. Then, you intialize that variable, with an array of String ([String](), which is short for [String].init()).
Then, the compiler knows what's the type of arr with its initialization.
That's the Type Inference.
But if you write:
var arr = []
Compiler won't know what's arr, you need to tell it when declaring the variable with myVar: ItsType, or upon the initialization, if with = [String]().
So you'll get compiler error: Empty collection literal requires an explicit type.
Usually, using both is overkill, too verbose.
You could then also write:
// Using Type Annotation:
// Declaring the variable type, the initialization doesn't need to specify it
var arr: [String] = []
var arr: Array<String> = []
// Using Type inference:
// Initialization is expliciting the type, the type is then "guessed".
var arr = [String]()
var arr = [String].init()
var arr = Array<String>()
var arr = Array<String>.init()
// Using Type Annotation & Type Inference:
// Declaring the variable type, AND also the on the initialization
var arr: [String] = [String]()
var arr: [String] = [String].init()
var arr: Array<String> = [String]()
var arr: Array<String> = [String].init()
In my case, I prefer var arr: [String] = []. But that's my opinion.
It's kind pretty straight forward to find an element in an array with type String, Int, etc.
var States = ["CA", "FL", "MI"]
var filteredStates = States.filter {$0 == "FL"} // returns false, true, false
Now, I created a struct
struct Candy{
let name:String
}
and then initialized it
var candies = [Candy(name: "Chocolate"),
Candy(name: "Lollipop"),
Candy(name: "Caramel")]
Can anyone please suggest the right way to find "Chocolate" in the array containing struct elements? I'm not able to implement the find or filter method.
With the following code you receive all candy structs in the array, which match to "Chocolate".
var candiesFiltered = candies.filter{$0.name == "Chocolate"}
If you just want a boolean if it has been found or not you could use the following code:
var found = candies.filter{$0.name == "Chocolate"}.count > 0