Making text into an array - Swift - swift

For fun I'm helping my school out by creating an app which has all class cancellations for student use. From my IT technician I got a quite complex structure containing class name, teacher, and other information looking like this:
3818,"20170217",5,752,64,"Rh",,"fr_2",,,,"iV5",,,"IS10a~IS10b~IS10c~IS10d","Z",,1,"IS10a~IS10b~IS10c~IS10d",C,201702161517,"-"
3819,"20170217",6,752,102,"Rh",,"fr",,,,"iB3","iB3",,"IT10a","Z",,0,"IT10a",,201702161517,"-"
3820,"20170217",8,752,119,"Rh",,"fr",,,,"iC1.2","iC1.2",,"IS6a","Z",,0,"IS6a",,201702161517,"-"
3821,"20170227",2,753,207,"Dd","Kru","sc",,,,"iB8","iB8",,"IS9b","Z",,2097152,"IS9b",,201702270804,"+~-"
3822,"20170227",3,753,8,"Dd",,"phH_1",,,,"iB8",,,"IS12~IT12","Z",,2097153,"IS12~IT12",C,201702270804,"-"
3823,"20170227",4,753,29,"Dd",,"phH_1",,,,"iB8",,,"IS11~IT11","Z",,2097153,"IS11~IT11",C,201702270804,"-"
3824,"20170227",5,753,30,"Dd",,"phH_1",,,,"iB8",,,"IS11~IT11","Z",,2097153,"IS11~IT11",C,201702270804,"-"
3825,"20170227",6,753,7,"Dd",,"phH_1",,,,"iB8",,,"IS12~IT12","Z",,2097153,"IS12~IT12",C,201702270804,"-"
3826,"20170227",7,753,327,"Dd",,"COV",,,,"AC1",,,,"Z",,2097153,,,201702270803,
3827,"20170227",8,753,46,"Dd",,"ph_1",,,,"iB8",,,"IS10a~IS10b~IS10c~IS10d~IT10a~IT10b","Z",,2097153,"IS10a~IS10b~IS10c~IS10d~IT10a~IT10b",C,201702270804,"-"
From this data I need to get various pieces, such as "20170217" and put them into an array for later use. How would I best do this? For anyone who cares, I added the full snippet below!
https://jsfiddle.net/pztwfsq1/

Since there is one dataset per line you can iterate through all lines. Split each line at , and you'll have an array of the information.
Similar to this (to give you an idea):
let row = "1,Peter,5,92,,Brooklyn"
let data = row.components(separatedBy: ",")
let name = data[1] // Peter
let location = data[5] // Brooklyn

Related

QgsField won't accept parameter typeName

I'm trying to create new vector layer with the same fields as contained in original layer.
original_layer_fields_list = original_layer.fields().toList()
new_layer = QgsVectorLayer("Point", "new_layer", "memory")
pr = new_layer.dataProvider()
However, when I try:
for fld in original_layer_fields_list:
type_name = fld.typeName()
pr.addAttributes([QgsField(name = fld.name(), typeName = type_name)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
I get a layer with no fields in attribute table.
If I try something like:
for fld in original_layer_fields_list:
if fld.type() == 2:
pr.addAttributes([QgsField(name = fld.name(), type = QVariant.Int)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
... it works like charm.
Anyway ... I'd rather like the first solution to work in case if one wants to automate the process and not check for every field type and then find an appropriate code. Besides - I really am not able to find any documentation about codes for data types. I managed to find this post https://gis.stackexchange.com/questions/353975/get-only-fields-with-datatype-int-in-pyqgis where in comments Kadir pointed on this sourcecode (https://codebrowser.dev/qt5/qtbase/src/corelib/kernel/qvariant.h.html#QVariant::Type).
I'd really be thankful for any kind of direction.

Eliminate repetition in updating strings selected randomly within a state property

First, I'm very new to Swift, and coding in general. I'm trying to use the correct terminology, so I apologize if it makes no sense. Doing my best!
Ok, so there appears to be a lot of information/answers on ways to random select strings (or integers, etc) from an array without repetition. However, in my current application, I am not using an array (I kind of am but not directly related to the question). But rather a #State designation, in which the variable has an initial value (a string with a number and letter) and is later updated when a button is pushed. The string changes to a randomly selected string from my assets folder based on the file name, which will be the same word but with a different number and letter. What is the simplest way to keep from updating to strings that have already appeared?
Example of what the code looks like:
#State var relevantWord = "bird"
Button {
let randoNum = Int.random(in: 1...5)
let x = ["a", "b", "c", "d"]
let randoLet = x.randomElement()
relevantWord = "bird" + String(randoNum) + String(randoLet)
}
So, the relevantWord variable starts as "bird2c" for example, and each time the button is pushed, it will change to "bird3b" then "bird4a" etc. I just want to keep it from repeating and return nothing when the assets are depleted. Thanks!

nim language ,gintro demo with two columns in a listview / gtktreeview and sortable

For nim language there is only one gui toolkit working for me and that is gintro.
The democode listview compiles and runs nice on my netbsd.
Source:
http://ssalewski.de/gintroreadme.html
But I need a listview(gtktreeview) with two columns, I looked into nim.gtk but can't figure out which "casts" I should spell.
The code in the demo program:
let gtype = typeFromName("gchararray")
let store = newListStore(N_COLUMNS, cast[pointer]( unsafeaddr gtype))
# cast due to bug in gtk.nim
Works nice for N_COLUMNS=1 but not N_COLUMNS:2
Here is the relevant part in nim.gtk:
proc newListStore*(nColumns: int; types: GTypeArray): ListStore =
let gobj = gtk_list_store_newv(int32(nColumns), types)
Second when I have multiple colums I would like to make it sortable by clicking on the header (like an excel table)
I think you need something like this:
let gtypes = [typeFromName("gchararray"), typeFromName("gchararray")] # Be sure to change the types to whatever you need.
let store = newListStore(N_COLUMNS, addr gtype[0]) # You shouldn't need this weird cast here.
Untested but should work. Feel free to join our Gitter/IRC if you need more help :)

How to load basic initial and unique data to Core Data in Swift?

I am working on a project and would like to have some initial data loaded to Core Data. There are two attributes in the Core Data. First belongs to body part and second belongs to its property. Such as Eyes to have one of the four colors and so forth. The data will be like following:
Eyes Blue
Eyes Brown
Eyes Green
Eyes Black
Hair Red
Hair Brunette
Hair Blonde
Clothes Dress
Clothes Skirt
Clothes Shoes
Clothes Hat
Clothes Gloves
I have searched some CSV or pList versions and heard some sqLite shipment alternatives but couldn't figure out how to do them effectively.
I appreciate any clear explanation to load small initial data to Core Data and also removing any duplicate value from Core Data, if exists. Thank you in advance.
Here is some very basic code to show one simple way of doing this.
You need to add your own identifier attribute so you can check if an item already exists. Let's say you call that id.
Then, when you start your app, you check for each of your default values and if they don't already exist, add them, like this:
// create a fetch request to get all items with id=1
let fr = NSFetchRequest<MyItem>(entityName: MyItem.entity().name!)
fr.predicate = NSPredicate(format: "id == %#", "1")
do {
// if that request returns no results
if (try myManagedObjectContext.fetch(fr).isEmpty == true) {
// create the default item
let item = NSEntityDescription.insertNewObject(forEntityName: MyItem.entity().name!, into: myManagedObjectContext) as! MyItem
// set the id
item.id = "1"
// set other attributes here
}
} catch {
// fetching failed, handle the error
}
After adding the data, you have to save it:
// save the context
do {
try myManagedObjectContext.save()
} catch {
// handle the error
}
You could also use Core Datas Unique Constraints, but I think this solution is much simpler. Hope this helps!

Creating UITabBarItem from an array

I'm writing an app that needs to create a number of tabs based on values from a database. It gets given a list of Pupils and Class numbers from a CSV file, and imports them into a database. I can run a SELECT DISTINCT on the database and I get a list of class numbers (eg -2, -1, R, 1, 2) and I can iterate through the list fine using
for class in classnumbers {
print (class[0])
}
and see a list of my class numbers, but I'm banging my head against a brick wall trying to generate the tabs at runtime. I've got the code:
let firstVc = UIViewController()
firstVc.title = "First"
firstVc.tabBarItem = UITabBarItem.init(title: "Home", image: UIImage(named: "HomeTab"), tag: 0)
tabBarCont.viewControllers = [firstVc]
This will create a tab when it loads like I expect, so I know that works, and I can add secondVC etc to create more... What I'm struggling with is using my class number instead of firstVC - so I'd like to be able to generate them like this:
for class in classnumbers {
let class[0]Vc = UIViewController()
class[0]Vc.title = "class[0]"
class[0]Vc.tabBarItem = UITabBarItem.init(title: "class[0]", image: UIImage(named: "class[0]"), tag: 0)
tabBarCont.viewControllers = [class[0]Vc]
}
and so on for each class in the database. I've seen the question answered with "use an array", but I can't see how that would be any different to looping round my database results, and I've seen "you can't do that with swift" - so is it do-able or do I need to come up with a different way of looking at the problem? (I won't know the class numbers / names that a school use until after getting their data - if I have to hard code them, I'd have to recompile the app for every different school?)