Auto add a class instance to an array in Swift - arrays

How can I auto add a new class instance to an array?
Example:
class Product {
var name: String?
}
var products = [Product]()
How can I add a new instance of a Product class to the products Array? How can I append to the array?
I tried some code but I don't know how to reference the class in own class.
I tried something like this:
class Product {
var name: String?
init() {
products.append(Produt)
}
var products = [Product]()
Thanks!

If you want your newly created object stored in products array then you need to declare it as static property so that it is shared by all instance otherwise it will just add first object for your every instance.
class Product {
var name: String?
static var products = [Product]()
init() {
Product.products.append(self)
}
init(name: String) {
self.name = name
Product.products.append(self)
}
}
Now use this products array using Product.products.
_ = Product(name: "One")
_ = Product(name: "two")
print(Product.products)

I dont't know why you need it, but you can use
class Product {
static var products: [Product] = []
var name: String?
init() {
products.append(self)
}
}

Have you tried products.append(self) ?

Related

How to handle data and data models in SwiftUI

I am having trouble with the structure of my data for creating a List in SwiftUI. Before SwiftUI I created my data models and held this data in separated files. For example,
In my UserModel.swift :
import SwiftUI
struct UserModel: Equateable {
var name: String
var items = [ItemModel]()
init(name: String, items: [ItemModel]? = nil) {
self.name = name
if let items = items {
self.items = items
}
}
}
In my ItemModel.swift :
import SwiftUI
struct ItemModel: Equatable {
var itemName: String
var price: Double
init(itemName: String, price: Double) {
self.itemName = itemName
self.price = price
}
}
Then I had a separate class called Data that held this data.
In my Data.swift :
import Foundation
class Data {
static var userModels = [UserModel]()
static var itemModels = [ItemModel]()
}
I would update the data by doing something like this in my views:
let user = UserModel(name: "Bob")
Data.userModels.append(user)
I'm having trouble populating a List from this framework in SwiftUI. I tried to make both of my model classes conform to Identifiable but that doesn't seem to help in updating the list. This is what I'm doing so far:
Updated UserModel :
struct UserModel: Identifiable {
var id = UUID()
var name: String
var items = [ItemModel]()
init(id: UUID, name: String, items: [ItemModel]? = nil) {
self.id = id
self.name = name
if let items = items {
self.items = items
}
}
}
Updated ItemModel:
struct ItemModel: Identifiable {
var id = UUID()
var itemName: String
var price: Double
init(id: UUID, itemName: String, price: Double) {
self.id = id
self.itemName = itemName
self.price = price
}
}
And in my ContentView.swift
List (Data.userModels) { user in
Text("\(user.name)")
}
But this does not update the List when I am running the app. (Btw I take input from TextField, append it to Data.userModels, and try to populate it in the List with no luck.)
Is there a different way I should be structuring my data and data models? Or am I just not using the proper syntax when creating the list? Sorry for the long question. Thanks for the help!

Create an object array from another object array and reconstruct the original object array later using map

Consider the following classes
class Category {
var tag: String?
var itemList: [Item]?
}
class Item {
var id: Int?
var type: String?
var itemDetails: ItemDetails?
}
class ItemDetails {
var description: String?
var name: String?
var price: Float?
}
Given an array of Category objects.
var categoryList: [Category]
I want to create a new object array by extracting only the name in ItemDetails(inorder to apply a filter) and an id inorder to reconstruct back array of Category objects.
Hence, I have to reconstruct the array of Category objects
from new object array.
How to do both extraction and reconstruction using the map feature?
Below are the examples of other data sources:
Datasource 1 :
var categoryList: [Category], where name need to be extracted
Datasource 2 :
var searchList = [SearchItem], where title to be extracted.
Class SearchItem {
var id: Int?
var details: SearchItemDetails?
var type: String?
}
Class SearchItemDetails {
var description: String?
var title: String?
}
DataSource 3
var products: [Products], where title to be extracted.
Class Products {
var id: Int?
var details: ProductDetails?
var type: String?
}
class ProductDetails {
var description: String?
var title: String?
}
To get an array of just the names, you do the map like you mentioned:
let categories: [Category] = ... // this already exists
let itemNames = categories.map { $0.itemList?.map({ $0.itemDetails?.name }) }
But this will preserve optionals. If you don't want optionals, then use compactMap instead.
Reconstructing, however, doesn't really make any sense. Are you using the ID to hit a database or network service? That's the only possible way you'd be able to reconstruct the original array of Categorys. Why not just hold onto the original array?

How to print elements of one class using variable of another class?

I have created two classes a Person class and a food class. Now i am making list of all the food items consumed in a year by a particular person. I want to print all of them separated by commas
Here's my code
class Food {
let name: String
var EatenBy: Person?
init(name: String){
self.name = name
}
}
And my Person class is as follows
class Person {
var name: String
var foods: [Food] = []
lazy var foodNames: () -> String = {
return ""
}
init(name: String){
self.name = name
}
func adopt(food: Food){
foods.append(food)
food.EatenBy = self
}
}
Now i want to create different food items using the Food class and then assign it to a person who have consumed them and store it in an array foods.
var person = Person(name: "Test")
var pasta = Food(name: "pasta")
Can anyone help me out how can i use the objects created using Food class and assign it to a object created in the Person class and append them in the foods array ?
My final aim is to print all the elements in the foods array separating them using commas or spaces or such, which i guess can be easily done by looping each of the element through a for loop ?
Using a Person instance, you can access its properties (including the foods array by the dot syntax: person.foods.
For printing the food names, you should declare foodNames as a computed property. As its return value, just use map to get the names of each Food instance, then use [String].joined(separator: ",") to join the contents of the array of Strings into a single String.
class Person {
var name: String
var foods: [Food] = []
var foodNames:String {
return foods.map{$0.name}.joined(separator: ",")
}
init(name: String){
self.name = name
}
func adopt(food: Food){
foods.append(food)
food.EatenBy = self
}
}
class Food {
let name: String
var EatenBy: Person?
init(name: String){
self.name = name
}
}
let john = Person(name: "John")
let pasta = Food(name: "pasta")
john.foods = [pasta, Food(name: "tuna")] //assign an array to the variable directly
john.foods.append(Food(name: "tomato")) //or append the existing array
john.adopt(food: Food(name: "bread")) //you can also use your _adopt_ function to add an element to the _foods_ array of a _Person_ instance
john.foodNames // "pasta, tuna, tomato,bread"
It looks like you are missing some basic concepts of how Swift works (like using the dot syntax to access class properties), so I would recommend reading The Swift Programming Language Guide as a start, it is a really useful starting point for a beginner Swift developer.

Swift Realm [[String]] object

I'm new to Realm and have been through the documentation a few times. I need to persist a [[String]] and have not found a way to do it yet
var tableViewArray = [[String]]()
I see the documentation pointing to Lists but I've been unsuccessful at implementing them. I'm showing my whole process here but just need help persisting my var tableViewArray = [[String]]()in Realm
This is my class
class TableViewArrays {
var tableViewArray = [[String]]() // populates the Main Tableview
/// add picker selection to tableview array
func appendTableViewArray(title: String, detail: String, icon: String ) {
var newRow = [String]()
newRow.append(title)
newRow.append(detail)
newRow.append(icon)
tableViewArray.append(newRow)
}
In the View Controller I instantiate the object
var tableViewArrays = TableViewArrays()
Then call the class function to populate the object
var tableViewArrays.appendTableViewArray(title: String, detail: String, icon: String )
Thank you for taking a look
I would make two Realm objects to be persisted, then nest them. Here's an example:
class RealmString: Object {
dynamic var value = ""
}
class RealmStringArray: Object {
let strings = List<RealmString>()
}
class TableViewArray{
let stringArrays = List<RealmStringArray>()
}
I can't say much about the efficiency of this method, but I suppose it should work for your purpose. Also, if you have a large amount of data, it may become a pain to persist each individual string, then string collection, the string collection collection.
create the classes
class TableViewRow: Object {
dynamic var icon = ""
dynamic var title = ""
dynamic var detail = ""
override var description: String {
return "TableViewRow {\(icon), \(title), \(detail)}" }
}
class EventTableView: Object {
let rows = List<TableViewRow>()
}
then instantiate the objects and append
let defaultTableview = EventTableView()
let rowOne = TableViewRow()
rowOne.icon = "man icon" ; rowOne.title = "War Hans D.O.P." ; rowOne.detail = "Camera Order Nike 2/11/17"
defaultTableview.rows.append(objectsIn: [rowOne])

How to save an array to a Realm Object

I am new to using Realm. Is there an easy way to save an array to a realm object? I am receiving my data from a JSON REST call:
class SomeClass: RLMObject {
dynamic var id = 0
dynamic var name = ""
dynamic var array: NSArray
func checkForUpdates() {
// Download JSON data here... The results have an array inside of them.
SomeClass.createOrUpdateInDefaultRealmWithObject(SomeNSDictionary)
}
override class func primaryKey() -> String! {
return "id"
}
}
Is it possible to save the array in the JSON results in Realm?
Thanks.
Realm has a special RLMArray type, which allows storing a collection of RLMObject's tied to a parent RLMObject. For example, say you had the following JSON:
{
"name": "John Doe",
"aliases": [
{"alias": "John"},
{"alias": "JD"}
]
}
You could model this with the following classes:
class Alias: RLMObject {
dynamic var alias = ""
}
class Person: RLMObject {
dynamic var name = ""
dynamic var aliases = RLMArray(objectClassName: "Alias")
}
So you could simply create a Person object with the following API call:
Person.createInRealm(realm, withObject: jsonObject)
You can learn more about how RLMArrays work from Realm's reference documentation: http://realm.io/docs/cocoa/0.80.0/api/Classes/RLMArray.html

Resources