This is the 7th day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021
Previous posts: Swift Development Tips you May not have known — Pt.1
Group arrays
If you have a set of articles and want to group them by category, you can use the technique described in pt.1 to set a default value for a key in the dictionary as follows:
struct Article {
let title: String
let category: String
}
let articles = [
Article(title: "Heading 1", category: "Swift"),
Article(title: "Heading 2", category: "Swift"),
Article(title: "Title", category: "Objective-C"),
Article(title: "Title 4", category: "Objective-C"),]var groupByCategory = [String : [Article]] ()for article in articles {
groupByCategory[article.category, default: []].append(article)
}
print(groupByCategory)
Copy the code
We can actually use Dictionary’s built-in initialization method to simplify the for loop above:
let groupByCategory = Dictionary(grouping: articles, by: {$0.category})
print(groupByCategory)
Copy the code
Check that all collection items meet the criteria
Given an array of integers representing ages, find their average age. Calculate the sum, divide by the quantity, so easy~
However, not every integer can represent age, because the value passed in May be less than or equal to zero. For the input parameter: age array, is not controllable. So when you encounter an incorrect value, you need to throw an error. It is usually implemented like this:
func findAverage(ages: [Int]) -> CGFloat {
var isAgeValid = true
for age in ages {
if age < = 0 {
isAgeValid = false
break}}guard isAgeValid else {
fatalError("All ages must be greater than zero.")}let sum = ages.reduce(0.+)
let count = ages.count
return CGFloat(sum) / CGFloat(count)
}
findAverage(ages: [22.25.26.28.30])
Copy the code
We can use Array’s method allSatisfy(_:) to simplify the for loop:
func findAverage(ages: [Int]) -> Double {
let isAgeValid = ages.allSatisfy { $0 > 0 }
guard isAgeValid else {
fatalError("All ages must be greater than zero.")}let sum = ages.reduce(0.+)
let count = ages.count
return Double(sum) / Double(count)
}
findAverage(ages: [22.25.26.28.30])
Copy the code
Keep the Struct’s default initializer
As you all know, structs in Swift are value types that come with a member initializer.
I don’t know if you’ve ever had a situation where you need to customize the initializer for a Struct, but you want to keep the default initializer, but when you customize it, the default initializer disappears.
Take a look at the default initializer:
When you customize an initializer, the default initializer disappears:
If you want to keep both custom and default extensions, use the extension method:
Filter nil in an array
When it comes to filtering, the first reaction might be filter(_:) :
let x = [1.nil.2.4]
let y = x.filter { $0 ! = nil }
Copy the code
It can be done, but not so well. The type of x above [Int?] And so is y. What’s the problem? The problem is, we already know that y doesn’t contain nil, but the compiler doesn’t know that, so we still need to unpack the elements as we traverse y:
let x = [1.nil.2.4]
let y = x.filter { $0 ! = nil }
for item in y {
print("item is \(item!)")}Copy the code
It is better to use compactMap(_:) :
let x = [1.nil.2.4]
let y = x.compactMap { $0 }
Copy the code
Where x is Int? Y is the type of [Int].
zip
What would you do if you needed to iterate over two arrays at the same time? This is what I used to do before I knew zip:
let array1 = ["title1"."title2"."title3"."title4"]
let array2 = ["value1"."value2"."value3"."value4"."value5"]
let count = min(array1.count, array2.count)
for i in 0..<count {
let title = array1[i]
let value = array2[i]
}
Copy the code
Zip can combine two sequences and does boundary checking:
for (title,value) in zip(array1, array2) {
print("\(title)---\(value)")}// Output the result
title1---value1
title2---value2
title3---value3
title4---value4
Copy the code
conclusion
- Use Dictionary’s init(Grouping :by:) method to group arrays
- Use Array’s allSatisfy(_:) method to check that all collection items meet the criteria
- Retain the default initializer by adding a custom initializer through Extension
- Filter nil in an array using compactMap(_:)
- Combine two collections using ZIP
Previous posts: Swift Development Tips you May not have known — Pt.1
The above is usually used in the project more Swift tips, I will continue to summarize more tips and share ~
If you come across something you haven’t used before, give it a try