I'm trying to delete values of a lot of variables inside an array:
var fbUserID = String()
var fbUserName = String()
var meNickname = String()
var userIDOneSignal = String()
var deleteStrings = [fbUserID, fbUserName, meNickname, userIDOneSignal]
Is it possible to do something in line of this:
for i in deleteStrings {
i.removeAll()//remove all as in remove the values of each variable
}
I've also tried using deleteStrings[i].removeAll()
Due to value semantics you cannot mutate variables (as a pointer) from an array.
Rather than an array use a struct
struct User {
var fbUserID = "12"
var fbUserName = "Foo"
var meNickname = "Baz"
var userIDOneSignal = "123"
mutating func clear()
{
fbUserID = ""
fbUserName = ""
meNickname = ""
userIDOneSignal = ""
}
}
var user = User()
print(user.fbUserID) // "12"
user.clear()
user.fbUserID = ""
print(user.fbUserID) // ""
Simply delete the array elements
deleteStrings.removeAll()
If your class inherits from NSObject, you can use key value coding to access the fields by name:
class User: NSObject {
var fbUserID = String()
var fbUserName = String()
var meNickname = String()
var userIDOneSignal = String()
var deleteStrings = ["fbUserID", "fbUserName", "meNickname", "userIDOneSignal"]
func clearAll() {
deleteStrings.forEach { setValue("", forKey: $0) }
}
}
let user = User()
user.fbUserID = "12345"
user.fbUserName = "Joseph Doe"
user.meNickname = "Joe"
print(user.meNickname) // "Joe"
user.clearAll()
print(user.meNickname) // ""
If you want to delete/remove variable value then use optional otherwise your variable value only gets removed or become non-existence when it goes out of scope.
For Example:
var a: Int? = 5 // it have default value 5
a = nil // Now a have nil which is kind of telling that it contains nothing which is what you want to achieve
Now coming to your question.
Is it possible to do something in line of this:
for i in deleteStrings {
i.removeAll()
}
You are iterating over an array of strings and then for each string, you are trying to remove all the characters. First of all you will get error
error: cannot use mutating member on immutable value: 'i' is a 'let' constant
Even though you will correct is using var it will not achieve what you are trying to do i.e. I want to delete the variables value because still your fbUserID ... all other variables will have copies of the data you initialised with.
Now how to do it?
You can use optional to achieve it.
var fbUserID: String? = String()
var fbUserName: String? = String()
var meNickname: String? = String()
var userIDOneSignal: String? = String()
// To delete you will need to assign them nil
fbUserId = nil
Again, you can't do them over loop because var are of values type and when you add it to the list their copies get added.
Related
I've an Array based on this struct :
struct Airports2: Identifiable, Codable, Hashable{
var AirportID: String = ""
var Icao: String = ""
var ApType: String = ""
var Name: String = ""
var Latitude: String = ""
var Longitude: String = ""
var Altitude: String = ""
var Continent: String = ""
var Country: String = ""
var Region: String = ""
var Municipality: String = ""
var Service: String = ""
var GpsCode: String = ""
var Iata: String = ""
var LocalCode: String = ""
var Link: String = ""
var wikiLink: String = ""
var Keyword: String = ""
let id = UUID()
}
And I would like to create a function which have as Parameter a String corresponding to the ICAO and from the ICAO find the airport Latitude and save only the Latitude in a simple var and return it.
My Airport array is declared as follow :
var FR_airportsDB = [Airports2]()
And my "searching function" is like that :
func getApLat(ApName: String) -> Double{
let LAT: Double
var latFindString = FR_airportsDB.contains(Airports2.init(Icao: ApName))
LAT = Double(latFindString)!
return LAT
}
But this is not working, I think .contains is not the best to use but I don't know how to make a search in a structured array.
Hope to be clear about my problem ..
Thanks for your help
First of all please name your variables lowerCamelCase according to the naming convention and name your struct in singular form
var frAirportsDB = [Airport2]()
To search for a value of a specific property try to get the first item in the array where the value of this property is equal to the value in the parameter.
You have to return an optional because the item might be not available and the string could not be converted to Double
func getApLat(apName: String) -> Double? {
guard let foundAirport = frAirportsDB.first(where: {$0.Icao == apName}),
let lat = Double(foundAirport.Latitude) else { return nil }
return lat
}
And please add CodingKeys to convert the uppercase keys to lowercase property names. And all default values in the struct are not necessary. The code compiles even without.
I am trying to get all characters in an array, when user types something.
In my codes; when I type “hello” and print it, I get:
arrRegular: [“h”]
arrRegular: [“e”]
arrRegular: [“l”]
arrRegular: [“l”]
arrRegular: [“o”]
How can I make all characters in one array, like [“h”, “e”, “l”, “l”, “o”]
My codes:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
var arrRegular = [String]()
var arrBold = [String]()
var arrCombined = [String]()
if boldFont == false {
arrRegular.append(text)
} else {
arrBold.append(text)
}
arrCombined.append(contentsOf: arrRegular)
arrCombined.append(contentsOf: arrBold)
print(arrCombined)
return true
}
your var var arr = [String]() is local and is created every call of shouldChangeTextIn which is called every type of a character
You need to
let arr = Array(textView.text!)
or
let arr = textView.text.map { "\($0)" }
print(arr)
let text = textView.text ?? ""
let array = Array(text)
I have following struct:
struct PalletScan: Codable {
var deliveryId: String?
var userId: String?
var timestamp: String?
var tempPalletNr: String?
var tempLocation: String?
var tempPalletType: String?
var pallets: [MovementScan]?
//coding keys requried for translation API -> struct -> CoreData and CoreData -> struct -> API
enum CodingKeys: String, CodingKey {
case deliveryId = "TOID"
case userId = "UserId"
case timestamp = "TimeStamp"
}
mutating func appendMovementScan() {
var movementScan = MovementScan()
movementScan.locationId = self.tempLocation
movementScan.palletId = self.tempPalletNr
movementScan.palletType = self.tempPalletType
movementScan.timestamp = String(Date().timeIntervalSince1970)
print(movementScan)
self.pallets?.append(movementScan)
}
}
however self.pallets?.append(movementScan) does not adding anything to the pallets array. What am I missing? It must be trivial but can not find mistake.
Just change var pallets: [MovementScan]?
to
var pallets: [MovementScan] = [MovementScan]()
as #Carcigenicate you call append on nil value
var pallet is not initialized and it is an optional so when you append movementscan using ? , it wont be executed.
To fix this you have to some how initialize pallets array before appending to it .
One way can be simply initialize with empty array :
var pallets = [MovementScan]()
I have a table view which displays a user's Name, Company Name and Photo (PFFile). Each tableView row I have has all of this information in it.
I am using UISearchBarDelegate and IB to implement a search function to filter by the user's Name. It is finding the correct user but I have not been able to also update the company photo.
How do I filter the other arrays? The items I need from the arrays will be at the same index as the ones taken from the user's Name array.
EDIT: I am trying a different data structure and am receiving array index out of range, updated code below:
var filterArray = [User]() //<-- globally declared
var userArray = [User]() //< Global
class User {
var name: String?
var company: String?
init (name: String?, company: String?) {
self.name = name
self.company = company
}
}
//In a class which populates the search arrays
for object in unwrappedSucceeded {
let username = object.valueForKey("username") as! String
let companyName = object.valueForKey("companyName") as! String
let user = User(name: username, company: companyName)
userArray.append(user)
}
//tableViewController
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
filterArray.removeAll(keepCapacity: false)
if searchText.characters.count != 0 {
isSearch = true
self.search(searchText)
} else {
isSearch = false
}
}
func search(text: String) -> Void {
filterArray = userArray.filter({$0.name == text})
}
//In cellForRowAtIndexPath
cell.usernameCell.text = filterArray[indexPath.row].name //ARRAY INDEX OUT OF RANGE
Like I said you strongly recommend to group each user's info into one big container, therefore we could use array of struct or class, then it comes easier to filter.
schematic for the container:
struct Container
{
var username:String?
var companyName:String?
var photo:UIImage?
}
your main array will be : var arrayofData = [Container]()
Now when you are query your objects from parse, inside of your query function
// after you called the findObjectsWithBackgroundBlock()
// let's assume you check for error and if the [PFObject] is empty or not
for one in objectsFromParse
{
let photoToget = one["Photo"] as! PFFile
// next step should be to get the image data right :)
{
// let's assume that is the block when get the image data right:)
// check your data and assign it to some UIImage
// then
let userRepresentation = Container() //<-- we are creating a single object representation for each user
let username = one["username"] as! String //<--data we got from Parse
let companyName = one["companyName"] as! String
let userImage = //the UIImage which contains the data
userRepresentation.username = username
userRepresentation.companyName = companyName
userRepresentation.photo = userImage
// then we append
arrayOfData.append(userRepresentation)
}
}
Now we have all data into our array, so let's filter by username and also I hope you configure your tableView so when you have data from filter or regular array.
var filterArray = [Container]() //<-- globally declared
func search(text: String) -> Void
{
filterArray = arrayOfData.filter(){ (Container) -> Bool in
let range = Container.name!.rangeOfString(text, options:NSStringCompareOptions.CaseInsensitiveSearch) return range != nil }
// then you are good to go
}
let arr1 = [10,20,40]
let e1 = arr1.enumerate()
let arr2 = ["a","b","c"]
let f1 = e1.filter { $0.element % 20 == 0 }
let f2 = arr2.enumerate().filter { j, _ in
f1.contains { i, _ in
i == j
}
}
print(f1.map{$0.element}, f2.map{$0.element})
// [20, 40] ["b", "c"]
now you have both arrays "filtered". the best, what you can do is redesigning your data model!
Let say I have values like this
Apple(100)
Orange(300)
Pineapple(10)
Grape(50)
Banana(1000)
What I want to do is to create an array which was like that to each string
["Apple","100"]
["Orange","300"]
What i tried was like that,but it doesn't meet my answer well enough
var myNewFruits = "Apple(200)"
var newStr = myNewFruits.componentsSeparatedByString("(")
The Output was
["Apple","200)"]
What i really want was
["Apple","200"]
Is there any help with Swift?Thank you.Because I am creating search with that,so,i really need it.
You can use a custom NSCharacterSet and get the first two elements from the returned array:
let myNewFruits = "Apple(200)"
let newStr = myNewFruits.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "()"))[0...1] // ["Apple", "200"]
You can do it this way:
func stringToArr(str: String) -> [String] {
var newArr = [String]()
var fullNameArr = split(str) {$0 == "("}
newArr.append(fullNameArr[0])
var last: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil
newArr.append(last!.stringByReplacingOccurrencesOfString(")", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil))
return newArr
}
var string = "Apple(100)" //"Apple(100)"
let newArr = stringToArr(string) //["Apple", "100"]