How to Create Optional Struct with Arrays - arrays

I would like to create the following struct/array combination; however, I'm getting lost in the array nesting. Is this the proper way to set up a "City", and if so, what would be the best practice technique to modify it, so that I can init new Cities with a different customer value?
Thanks!
struct City {
var name: String
var groceryStores: [GroceryStore]
}
struct GroceryStore {
var name: String
var employeesAtInterval = [employeeIDs]
}
var employeeIDs = [40, 20, 13, 44]

Based on your code, this seems like what you wanted to achieve:
struct City {
var name: String
var groceryStores: [GroceryStore]
}
struct GroceryStore {
var name: String
// As employeeIDs are Ints, you should initialize it using this syntax
var employeesAtInterval = [Int]()
}
let employeeIDs1 = [40, 20, 13, 44]
let employeeIDs2 = [40, 20, 13, 44]
...
let groceryStore1 = GroceryStore(
name: "store 1",
employeesAtInterval: employeeIDs1
)
let groceryStore2 = GroceryStore(
name: "store 2",
employeesAtInterval: employeeIDs2
)
...
let city1 = City(name: "city 1", groceryStores: [groceryStore1, groceryStore2])
let city2 = City(name: "city 2", groceryStores: [groceryStore3, groceryStore4])
let cities = [city1, city2]

Related

Array of instances: Transform one specific value, in each instance, return a new array

struct Person {
var name: String
var age: Int
var weight : Int
var shoeSize: Int
}
struct Group {
var members : [Person]
}
let mygroup = Group(members: [
Person(name: "Billy", age: 59, weight: 170, shoeSize: 9),
Person(name: "Jacob", age: 19, weight: 130, shoeSize: 11),
Person(name: "Zara", age: 25, weight: 320, shoeSize: 10)
])
How can I multiple each age by 2, and return a new array (myGroupV2), but leave the other elements untouched?
You simply need to use map to apply a closure to each element of an Array. In your map closure, you need to initialise a new Person instance, where all inputs are the same as the properties of the original Person, except for age, which you multiply by 2.
let myGroup2 = Group(members: mygroup.members.map { Person(name: $0.name, age: $0.age * 2, weight: $0.weight, shoeSize: $0.shoeSize) })
Instead of individually assigning all the properties of Person, you can simply create a new Person instance and change its age property, i.e.
let myGroupV2 = mygroup.members.map {(person) -> Person in
var person = person
person.age *= 2
return person
}
In case you need it more than once, an extention can also be helpful:
extension Person {
var asDoubleAged: Person {
get {
return Person(name: self.name, age: self.age * 2, weight: self.weight, shoeSize: self.shoeSize)
}
}
}
let myGroupV2 = Group(members: mygroup.members.map { $0.asDoubleAged })
let personArray = mygroup.members.map { p in Person(name: p.name, age: p.age*2, weight: p.weight, shoeSize: p.shoeSize) }
let mygroup2=Group(members: personArray)
or
let mygroup2 = Group(members: mygroup.members.map { Person(name: $0.name, age: $0.age*2, weight: $0.weight, shoeSize: $0.shoeSize)})

Swift loop through array of dictionaries and create a new one

I'm struggling on getting a new array of dictionaries with conditioned 10 elements out of 80.
here is sample of students json:
{
"id": 111,
"name": "John",
"gender": "male",
"grade": 80,
"extraCredit": 20
},
{
"id": 112,
"name": "Jenny",
"gender": "female",
"grade": 85,
"extraCredit": 5
}
and my struct:
struct StudentData: Decodable {
var id: Int
var name: String
var grade: Int
var extraCredit: Int
}
I need to calculate each student's grade to get final grade and display top 10
here is my code to loop through:
var newStudentData = [Dictionary<String, Any>]()
for student in studentData {
let finalGrade = student.grade + (student.extraCredit * 0.5)
if finalGrade > 88 {
newStudentData.append(student) // error on cannot convert value type of ’StudentData’ to expected argument type ‘[String: Any]
}
}
what did I do wrong? or is there a better way?
newStudentData is a dictionary (why?), but you're appending instances of StudentData to it. This won't work.
That said, I would probably rewrite this like so:
struct StudentData: Decodable {
let id: Int
let name: String
let grade: Int
let extraCredit: Int
var finalGrade: Int {
return self.grade + self.extraCredit / 2
}
}
var students = [StudentData]()
// fill students array here
let beat88 = students.filter { $0.finalGrade > 88 }
let top10 = beat88.sorted { $0.finalGrade > $1.finalGrade }.prefix(10)

How can I count the item of property as an array inside a class?

How can I count the teamMember in team A?
class BasketBallTeam {
var teamName: String
var teamMember: [String]
init(teamName: String, teamMember: [String]) {
self.teamName = teamName
self.teamMember = teamMember
}
}
let highSchoolTeam: [BasketBallTeam] = [
BasketBallTeam(teamName: "A", teamMember: [
"John", "Sam", "Tom", "Ricky", "George"
]),
BasketBallTeam(teamName: "B", teamMember: [
"Jason", "Michael", "Daniel", "Henry", "David", "Luke"
]),
]
Just count it.
As highSchoolTeam is an array you have to get the first item
let numberOfMembers = highSchoolTeam.first?.teamMember.count
Please name teamMember in plural form teamMembers (or even members) to indicate the array
If you're doing this a lot, it would be best to create a dictionary that lets you easily access teams by their names:
struct BasketBallTeam {
var name: String
var members: [String]
init(name: String, members: [String]) {
self.name = name
self.members = members
}
}
let highSchoolTeams: [BasketBallTeam] = [
BasketBallTeam(name: "A", members: [
"John", "Sam", "Tom", "Ricky", "George"
]),
BasketBallTeam(name: "B", members: [
"Jason", "Michael", "Daniel", "Henry", "David", "Luke"
]),
]
let teamsByName = Dictionary(uniqueKeysWithValues:
highSchoolTeams.lazy.map { team in (key: team.name, value: team) })
Which makes looking up any team by name fast and easy:
let teamA = teamsByName["A"]
let teamASize = teamA?.members.count
print(teamASize as Any)
If you only need to do this once, you can use first(where:):
let teamA = highSchoolTeams.first(where: { $0.name == "A"})
You can get the count for each team as follows:
for team in highSchoolTeam {
print(team.teamMember.count)
}
You can simply use,
first(_:) on highSchoolTeam to get the team where teamName == "A".
count on teamMember to get the total count of teamMembers from the BasketBallTeam object obtained in step-1.
It goes like,
let teamAMemberCount = highSchoolTeam.first{ $0.teamName == "A" }?.teamMember.count
print(teamAMemberCount) //Output: 5

How to get only the first value/property of each object

I am trying to get the first value, in other words each of the objects.name to be printed/logged.
In this example, I would like Tom, Tom, Fox
var tom = {
name: "Tom",
age: 23,
location: "London"
};
var tom2 = {
name: "Tom",
age: 21,
location: "London"
};
var fox = {
name: "Fox",
age: 23,
location: "London"
};
var arr = [tom, tom2, fox];
for (var i = 0; i < arr.length; i++) {
var objectArr = arr[i]
for (var prop in objectArr) {
var values = objectArr[prop];
console.log(values)
}
}
You can simply use forEach built-in array function. Array.forEach():
arr.forEach(function (arrayItem) {
var x = arrayItem.name;
console.log(x);
});
One short way would be:
var arr = [tom, tom2, fox];
console.log(arr.map(el => el.name));
Using the function map on Array to get an array with only the object field you want and then the console.log function can take an array for argument and print it.

UInt8 Array to Strings in Swift

I want to convert an Array of UInt8 to several strings
var BytesArray = [123, 9, 32, 236]
TO
var Srt0 = "123"
var Srt1 = "9"
var Srt2 = "32"
var Srt3 = "236"
As you say, the answer should be like that-
var BytesArray = [123, 9, 32, 236]
var sort0:String = String(BytesArray[0])
var sort1:String = String(BytesArray[1])
var sort2:String = String(BytesArray[2])
var sort3:String = String(BytesArray[3])
Do you mean the following?
var bytesArray = [123, 9, 32, 236]
let stringArray = bytesArray.map( { "\($0)" })
print(stringArray)
This will produce an array of strings.
var BytesArray: [Int] = [123, 9, 32, 236]
var stringArray = BytesArray.map
{
String($0)
}
stringArray will become ["123", "9", "32", "236"]

Resources