How to print variables in structs in arrays? - arrays

With this Swift 3.0 lines:
struct Person {
var name: String
var surname: String
var phone: Int
var isCustomer: Bool
}
var contacts: [Person] = []
contacts.append(Person(name: "Jack", surname: "Johnson", phone: 2, isCustomer: false))
contacts.append(Person(name: "Mike", surname: "Morris", phone: 3, isCustomer: true))
I have created an array that includes two structures which include 4 variables each.
I can print a single object of the array like this: print(contacts[0].name)
but is there any way to print all the Strings of the name section at once?

Learn how to use map. I use it all the time.
print(contacts.map({ $0.name }))
Search for map in this Apple Documentation about Closures

You'll have to iterate over the array, either printing the values as you go, or capturing them into a string and printing them all at once.
Here's one way:
for contact in contacts {
print(contact.name)
}
Here's another:
contacts.forEach { print($0.name) }
Finally, you could join all the strings into one value with a separator and just print once. When you do it this way the joinWithSeparator function iterates the array for you:
let names = contacts.map { $0.name }
let joinedNames = names.joinWithSeparator(" ")
print(joinedNames)

You should implement the protocol CustomStringConvertible by defining the computed property description:
struct Person: CustomStringConvertible {
var name: String
var surname: String
var phone: Int
var isCustomer: Bool
var description: String {
return
"Name: \(name)\n" +
"Surname: \(surname)\n" +
"Phone: \(phone)\n" +
"Is Customer? \(isCustomer)\n"
}
}
And then:
var contacts: [Person] = []
contacts.append(Person(name: "Jack", surname: "Johnson", phone: 2, isCustomer: false))
contacts.append(Person(name: "Mike", surname: "Morris", phone: 3, isCustomer: true))
print(contacts)
Obviously you can define description as you want.

Related

How do i add objects into an array from a Class in Swift?

This is my Friend class:
class Friend {
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
var description:String = ""
init(firstname: String, lastname: String, age: Int) {
self.firstName = firstname
self.lastName = lastname
self.age = age
}
}
This is where i'm supposed to declare and instantiate 5 Friend objects in the viewDidLoad function and to add them into 'friendList' array.
import UIKit
class ViewController: UIViewController {
var friendsList: [Friend] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
friendsList.append("John", "Doe", 20)
}
}
Swift tells me that "No exact matches in call to instance method 'append'" on the "friendsList.append" line.
you can use like Below if you are creating all friends Initially
let friends = [Friend(firstname: "John", lastname: "Doe", age: 20),Friend(firstname: "doe", lastname: "John", age: 21)]
for friend in friends{
friendsList.append(friend)
}
//////////////////////////////////////
(or) you can directly declare value for your global variable
friendsList = [Friend(firstname: "John", lastname: "Doe", age: 20),Friend(firstname: "doe", lastname: "John", age: 21)]
///////////////////////////////////////////
(or) assign local variable value to your global variable
friendsList = friends
or if you adding One by One,You have to create object first
let friendOne = Friend(firstname: "John", lastname: "Doe", age: 20)
friendsList.append(friendOne)
The Array (Actually collection) function append takes a parameter of type <T> where T is a generic type, "the type of the elements in the array".
So if you have an array of Strings, you need to pass a String into append:
var strings = [String]()
strings.append("a string")
Since you have an array of Friend objects, you need to pass an instance of Friend to the append(_:) function. Does the expression inside the parentheses in your call to append evaluate to a friend object?
friendsList.append("John", "Doe", 20)
It doesn't. You'r passing a comma-separated list of properties. Presumably, those are the first name, last name, and age of a Friend, but the append() function doesn't know that.
You could write it as:
let aFriend = Friend(firstname: "John", lastname: "Doe", age: 20)
friendList.append(aFriend)
Or all in one line with:
friendList.append(Friend(firstname: "John", lastname: "Doe", age: 20))
Both of those variations would work.

Swift - Check if a value belongs is in an array

I have an array of type "User" and I would like to check if a value belongs to a property type.
My code :
struct User: Identifiable {
var id = UUID()
var name: String
var age: String
}
var array: User = [
User[name: "AZE", age: "10"]
User[name: "QSD", age: "37"]
]
For example I'd like to know if "AZE" belongs to the property array "name". What is the function for retrieving this information. I hope you understood my problem and thank you for your answer.
First of all, arrays define with [Type] like [User]
Second of all init method calls as with (Arguments) like User(name: ,age:)
And last but not least, don't forget the ',' between elements of the array.
So
struct User: Identifiable {
var id = UUID()
var name: String
var age: String
}
var array: [User] = [
User(name: "AZE", age: "10"),
User(name: "QSD", age: "37")
]
So now you can check your element inside with contains like
array.contains(where: { user in user.name == "AZE" }) // returns `true` if it is
Tips
Try name arrays not array. Use plural names instead like users
To returtning the found one:
users.first(where: { user in user.name == "AZE" })
To summarizing it
users.first { $0.name == "AZE" }

Creating an array of struct without duplicates

Recently started learning Swift and is now faced with the problem (code below will insert):
I create an array of structure from 3 arrays. When creating an instance of the structure, I need to do it by random (randomElement as I understood) - all 3 parameters must be unique. How do I check for uniqueness in the function?
arrayOfHumans = createRandomHuman()
struct Human {
let name: String
let surname: String
let age: String
var email: String
}
var arrayOfHumans = [Human] ()
var humans: [Human] = []
let nameA = ["Tim", "Mike", "Stan"]
let surnameA = ["Burk", "Sims", "Stoch"]
let ageA = ["12", "30", "25"]
let emailA = ["one#live.com", "two#gmail.com", "three#outlook.com"]
func createRandomHuman() -> [Human] {
for _ in 1...3 {
if nameA.isEmpty == false {
let human = Human(name: nameA.randomElement()!,
surname: surnameA.randomElement()!,
age: ageA.randomElement()!,
email: emailA.randomElement()!)
humans.append(human)
}
}
return humans
}
Actual result:
first Struct {
name: Tim
surname: Sims
age: 12
email: three#outlook.com
}
second Struct {
name: Mike
surname: Stoch
age: 25
email: one#live.com
}
third Struct {
name: Stan
surname: Burk
age: 30
email: two#gmail.com
}
A solution is to shuffle the surname, age and email arrays separately to get a random but unique order.
let nameA = ["Tim", "Mike", "Stan"]
let surnameA = ["Burk", "Sims", "Stoch"]
let ageA = ["12", "30", "25"]
let emailA = ["one#live.com", "two#gmail.com", "three#outlook.com"]
func createRandomHuman() -> [Human] {
let shuffledSurnameA = surnameA.shuffled()
let shuffledAgeA = ageA.shuffled()
let shuffledEmailA = emailA.shuffled()
var humans: [Human] = []
for i in 0..<nameA.count {
let human = Human(name: nameA[i],
surname: shuffledSurnameA[i],
age: shuffledAgeA[i],
email: shuffledEmailA[i])
humans.append(human)
}
return humans
}
let arrayOfHumans = createRandomHuman()
Another way is to shuffle the indices
func createRandomHuman() -> [Human] {
let indices = nameA.indices
let shuffledIndices = (0..<3).map{ _ in indices.shuffled()}
var humans: [Human] = []
for i in 0..<nameA.count {
let human = Human(name: nameA[i],
surname: surnameA[shuffledIndices[0][i]],
age: ageA[shuffledIndices[1][i]],
email: emailA[shuffledIndices[2][i]])
humans.append(human)
}
return humans
}
If I understand you right, you want to ensure that all randomly created humans are different.
If so, the question is when are 2 humans different. This depends on your problem. Thus you as the programmer have to define it.
You can do it by adopting the Equatable protocol.
As soon as your structs conform to this protocol, you can loop through all previously initiated humans, and check if the new randomly created one is equal to one of them. If so, create a new one.

Sort array of dictionaries where key is unknown

I have an array of dictionaries of type [[String:SchoolModel]]. The keys are the id of the school and then the school model contains info about the school like its name for example. I want to sort this array by SchoolModel.name, but can't figure out how since my key is a unique id for every element in the array.
struct SchoolModel {
var name: String
var city: String
var state: String
}
You can access the first value of each dictionary iterated to get the name.
struct SchoolModel {
var name: String
var city: String
var state: String
}
let schools: [[String:SchoolModel]] = [
["1": SchoolModel(name: "1", city: "a", state: "x")],
["2": SchoolModel(name: "2", city: "b", state: "y")],
["3": SchoolModel(name: "3", city: "c", state: "z")]
]
print(schools.sorted {
guard
let a = $0.values.first?.name,
let b = $1.values.first?.name else { return false }
return a < b
})
However, you should consider adding an id property to your struct. You can make it optional so you can still initiate a SchoolModel that hasn't been created yet.
struct SchoolModel {
var id: String?
var name: String
var city: String
var state: String
}
Then where ever you are populating the array of dictionaries, append the SchoolModel object without embedding it inside a dictionary, resulting in an array of type [SchoolModel].

Finding value in array containing custom class

I'm trying to find the place of a value in a an array containing structures.
My array looks like this
struct User {
var firstName: String?
var lastName: String?
}
var allThePeople = [User(firstName: "John", lastName: "Doe"), User(firstName: "Jane", lastName: "Doe"), User(firstName: "John", lastName: "Travolta")];
Is there a way to get the places for all "Doe"'s in the array? (in this case 0 and 1)
You can filter allThePeople with a condition to get all the people with the last name "Doe".
let allTheDoes = allThePeople.filter { $0.lastName == "Doe" }
You can enumerate the array and flat map it to an array of indices.
let allTheDoeIndexes = allThePeople.enumerated().flatMap { $0.element.lastName == "Doe" ? $0.offset : nil }
= allThePeople.enumerated().flatMap { $1.lastName == "Doe" ? $0 : nil }
If you want the actual indices, use something like
struct User {
var firstName: String?
var lastName: String?
}
var allThePeople = [User(firstName: "John", lastName: "Doe"), User(firstName: "Jane", lastName: "Doe"), User(firstName: "John", lastName: "Travolta")]
var indices = [Int]()
for i in 0 ..< allThePeople.count {
if allThePeople[i].lastName == "Doe" {
indices.append(i)
}
}
indices // [0,1]
otherwise use filter as #Callam suggested.

Resources