How to put a variable in a for loop with different end number - swift

I’ve got multiple variables with the same name but a different number on the end like this:
MyVar1, MyVar2, MyVar3, MyVar4
and they are either true or false
How do I write this correctly?
For index in Range(1...4){
if (“MyVar” + index) == true{
print(“:)”)
}
}

didnt tries the solution but according to this post: https://stackoverflow.com/a/45622489/5464805 you can do this:
Edit: I read that your variables are Booleans
for i in 0...4 {
if let var = myObject.value(forKey: "MyVar\(i)") as Bool,
var { // If var is successfully cast and true it enters the statement
print(var)
}
}
HOWEVER
All the other solutions above or below are still correct. This is something you dont usually do in Swift in general unless you must do so.
You should either rewrite your model and give a proper name to each variables, that you will later put into an array such as...
class MyObject {
var MyVar1: Bool // To Rename
var MyVar2: Bool // To Rename
var MyVar3: Bool // To Rename
var MyVars: [Bool] {
get { return [MyVar1, MyVar2, MyVar3] }
}
}
Or you completely get rid of these variable and create an Array directly
class MyObject {
// var MyVar1: Bool // To Delete
// var MyVar2: Bool // To Delete
// var MyVar3: Bool // To Delete
var MyVars: [Bool]
}
and you set the Array / Dictionnary in accordance to your needs

You are trying to get a sum of String ("MyVar") and Int ("index") and compare that sum with Bool (true)
It would be more safety to store all your variables in an array like that
let myVars = [MyVar1, MyVar2, MyVar3, MyVar4]
Then you can iterate throught the array:
for i in myVars {
if i {
print(i)
}
}

You can't create a variable from concatenation at runtime , you need to have an array of bool like this
var arr = [false,true,true,false] // var1 , var2 , var3 , var4
for item in arr {
if item {
}
}

Related

Change parameter of an object if list has a specific key [duplicate]

I am still not sure about the rules of struct copy or reference.
I want to mutate a struct object while iterating on it from an array:
For instance in this case I would like to change the background color
but the compiler is yelling at me
struct Options {
var backgroundColor = UIColor.blackColor()
}
var arrayOfMyStruct = [MyStruct]
...
for obj in arrayOfMyStruct {
obj.backgroundColor = UIColor.redColor() // ! get an error
}
struct are value types, thus in the for loop you are dealing with a copy.
Just as a test you might try this:
Swift 3:
struct Options {
var backgroundColor = UIColor.black
}
var arrayOfMyStruct = [Options]()
for (index, _) in arrayOfMyStruct.enumerated() {
arrayOfMyStruct[index].backgroundColor = UIColor.red
}
Swift 2:
struct Options {
var backgroundColor = UIColor.blackColor()
}
var arrayOfMyStruct = [Options]()
for (index, _) in enumerate(arrayOfMyStruct) {
arrayOfMyStruct[index].backgroundColor = UIColor.redColor()
}
Here you just enumerate the index, and access directly the value stored in the array.
Hope this helps.
You can use use Array.indices:
for index in arrayOfMyStruct.indices {
arrayOfMyStruct[index].backgroundColor = UIColor.red
}
You are working with struct objects which are copied to local variable when using for in loop. Also array is a struct object, so if you want to mutate all members of the array, you have to create modified copy of original array filled by modified copies of original objects.
arrayOfMyStruct = arrayOfMyStruct.map { obj in
var obj = obj
obj.backgroundColor = .red
return obj
}
It can be simplified by adding this Array extension.
Swift 4
extension Array {
mutating func mutateEach(by transform: (inout Element) throws -> Void) rethrows {
self = try map { el in
var el = el
try transform(&el)
return el
}
}
}
Usage
arrayOfMyStruct.mutateEach { obj in
obj.backgroundColor = .red
}
For Swift 3, use the enumerated() method.
For example:
for (index, _) in arrayOfMyStruct.enumerated() {
arrayOfMyStruct[index].backgroundColor = UIColor.redColor()
}
The tuple also includes a copy of the object, so you could use for (index, object) instead to get to the object directly, but since it's a copy you would not be able to mutate the array in this way, and should use the index to do so. To directly quote the documentation:
If you need the integer index of each item as well as its value, use
the enumerated() method to iterate over the array instead. For each
item in the array, the enumerated() method returns a tuple composed of
an integer and the item.
Another way not to write subscript expression every time.
struct Options {
var backgroundColor = UIColor.black
}
var arrayOfMyStruct = [Options(), Options(), Options()]
for index in arrayOfMyStruct.indices {
var option: Options {
get { arrayOfMyStruct[index] }
set { arrayOfMyStruct[index] = newValue }
}
option.backgroundColor = .red
}
I saw this method in some code and it seems to be working
for (var mutableStruct) in arrayOfMyStruct {
mutableStruct.backgroundColor = UIColor.redColor()
}

Swift: How to keep updating a Dictionary inside another Dictionary correctly?

This is a little hard to explain, but I'll try my best. I am trying to update a Dictionary inside another Dictionary properly. The following code almost does what I need.
var dictionary = Dictionary<String, [Int : Int]>()
func handleStatsValue(tag: Int ) {
let currentValue: Int = dictionary["Score"]?[tag] ?? 0
dictionary["Score"] = [
tag : currentValue + 1
]
}
However, it seems the dictionary is overridden when the tag value changes (e.g. 1 to 2). I need Dictionary to have multiple dictionaries inside of it. Any tips or suggestions are deeply appreciated.
Edit: I'm trying to have multiple dictionaries nested inside a dictionary. It seems whenever the tag value is changed, the dictionary is overridden.
One way to write this would be:
func handleStatsValue(tag: Int) {
dictionary["Score", default: [:]][tag, default: 0] += 1
}
or, written without [_:default:]
func handleStatsValue(tag: Int) {
var scoreDictionary = dictionary["Score"] ?? [:]
scoreDictionary[tag] = (scoreDictionary[tag] ?? 0) + 1
dictionary["Score"] = scoreDictionary
}
However, it's not a good idea to use nested dictionaries to keep your data. Use a custom struct instead and try to avoid tags too:
struct DataModel {
var score: [Int: Int] = [:]
}
I think you need something like this to either increase the value for an existing tag or add a new tag if it doesn't exist
func handleStatsValue(tag: Int ) {
if var innerDict = dictionary["Score"] {
if let value = innerDict[tag] {
innerDict[tag] = value + 1
} else {
innerDict[tag] = 1
}
dictionary["Score"] = innerDict
}
}
Although the code looks a bit strange with the hardcoded key "Score", maybe it would be better to have multiple simple dictionaries instead, like
var score: [Int, Int]()
or if you prefer
var score = Dictionary<Int, Int>()

Dictionary in Dictionary value search

I am downloading information from a Firebase database and it is being inputted via a for loop into:
static var Reports = [String:[String:String]]()
I need to figure out a way to search the inside values for a certain string
I have messed around with this but can't seem to get it inside the inside dictionary (If that makes sense)
for values in Reports.count {
if let item = Reports["favorite drink"] {
print(item)
}
}
I need to have a search string then a number of times the value appears like so:
func findString(dict Dictionary) -> Int {
var ReportsLevel1 = 0
(for loop I'm guessing)
search here for string
return ReportsLevel1
}
Tip: the outside dictionary keys are not set in stone, they depend on what time and date the report was submitted
To find out the numberOfTimes in which "yourSearchString" appears you can do as follows
var numberOfTimes = 0
for internalDictionary in reports.values
{
for value in internalDictionary.values
{
if (value == "yourSearchString") { numberOfTimes += 1 }
}
}
or
let numberOfTimes = reports.flatMap { internalDictsArray in internalDictsArray.value.filter { $0.value == "yourSearchString" } }.count

how can I return a result from a function into a variable?

I have a variable :
var name = [Nick,John,Peter]
and a function:
func name(){
var personname = []
.......
return personname
}
the result of the function are the names of the people Nick,John,Peter. How can I return the result into the variable.I mean I do not want to write the names manually I want to populate them from the function, because the function display all of the names. I am beginner and I will be glad if you show me the right syntaxis.
var name = [????] = [personname()] or how????
You should use -> to return something from a function. Here is an example:
static let people = ["Nick", "John", "Peter"]
func getPerson(index: Int) -> String
{
return self.people[index] //index is number of a person, 0 will be the first one, 1 is second, etc.
}
func showTeam()
{
// some code
print("This is a first boy: \(self.getPerson[0])")
// some code
}

Swift language: How do I implement a dictionary of array values, and assign (ie. append) new values to the array?

Language: Swift
I declared a dictionary whose value is an array, like this:
var unloadedImagesRows = [String:[Int]]()
private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
print("addToUnloadedImagesRow 0: row: \(row)")
var unloadedRows = imagesRowForLocation(forLocation)
unloadedRows!.append(row)
}
private func imagesRowForLocation(location:String!) -> [Int]! {
var unloadedRows = unloadedImagesRows[location];
if unloadedRows == nil {
unloadedRows = [Int]()
unloadedImagesRows[location] = unloadedRows
}
return unloadedRows
}
private func someMethod() {
addToUnloadedImagesRow(rowIndex, forLocation: event.iconImg)
...
}
The "unloadedRows!.append(row)" works and I saw in my debugger works as I saw the count increased to 1.
However, the next time I retrieve the value as in line "var unloadedRows = unloadedImagesRows[location]", I get a result of an array containing 0 values.
How do I implement a dictionary of array values, and assign (ie. append) new values to the array?
var unloadedRows = imagesRowForLocation(forLocation)
unloadedRows!.append(row)
unloadedImagesRows[forLocation] = unloadedRows!
You retrieve the array by value, i.e. another instance of the array stored inside the dictionary gets created. Therefore you should set it back into the dictionary after appending a value