Group array by more than one property swift - arrays

Swift provides a method that converts array to dictionary on the basis of single property. Is it possible to group array to dictionary on the basis of more than one property. Something like following
For example we have array of objects containing name, age and gender
Person{
let name: String
let age: Int
let gender: String
}
And we have array containing persons
let array:[Person] = [Person(name: "Alex", age: 25, gender: "Male"), Person(name: "Sara", age: 25, gender: "Female")]
How can I group by multiple properties like name and age ?
Dictionary(grouping: array, by: { $0.name && $0.age })

You can group by anything that can become a key, in other words, by anything that is Hashable.
If you need to combine multiple properties, define a new type:
struct GroupingKey: Hashable {
let name: String
let age: Int
}
Dictionary(grouping: array, by: { GroupingKey(name: $0.name, age: $0.age) })

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" }

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].

How to print variables in structs in 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.

How to retrieve array of elements from array of structure in golang?

I am new to golang, and got stuck at this. I have an array of structure:
Users []struct {
UserName string
Category string
Age string
}
I want to retrieve all the UserName from this array of structure. So, output would be of type:
UserList []string
I know the brute force method of using a loop to retrieve the elements manually and constructing an array from that. Is there any other way to do this?
Nope, loops are the way to go.
Here's a working example.
package main
import "fmt"
type User struct {
UserName string
Category string
Age int
}
type Users []User
func (u Users) NameList() []string {
var list []string
for _, user := range u {
list = append(list, user.UserName)
}
return list
}
func main() {
users := Users{
User{UserName: "Bryan", Category: "Human", Age: 33},
User{UserName: "Jane", Category: "Rocker", Age: 25},
User{UserName: "Nancy", Category: "Mother", Age: 40},
User{UserName: "Chris", Category: "Dude", Age: 19},
User{UserName: "Martha", Category: "Cook", Age: 52},
}
UserList := users.NameList()
fmt.Println(UserList)
}
No, go does not provide a lot of helper methods as python or ruby. So you have to iterate over the array of structures and populate your array.
No, not out of the box.
But, there is a Go package which has a lot of helper methods for this.
https://github.com/ahmetb/go-linq
If you import this you could use:
From(users).SelectT(func(u User) string { return u.UserName })
This package is based on C# .NET LINQ, which is perfect for this kind of operations.

Resources