I want to count the frequency of false m's in an array of elements:
import UIKit
struct aW: Hashable, Codable {
var day: Int
var w: Double
var m: Bool
}
let array = [
aW(day: 0, w: 32.62, m: true),
aW(day: 1, w: 32.40, m: true),
aW(day: 2, w: 32.16, m: true),
aW(day: 3, w: 32.01, m: false),
aW(day: 4, w: 31.81, m: true),
aW(day: 5, w: 31.61, m: false),
aW(day: 6, w: 31.41, m: false),
aW(day: 7, w: 31.20, m: true),
aW(day: 8, w: 31.01, m: true),
aW(day: 9, w: 30.83, m: true)]
Also I want to select the first element with a false occurence.
I found a lot of examples for frequencies for arrays of strings or int's. But how do you do this with an array of such elements?
CodePudding user response:
You can simply use reduce. If the element's m
property is true return the same partial result otherwise return the partial result plus one:
let count = array.reduce(0) { $1.m ? $0 : $0 1 }
count // 3
To get the first element that is false you can use first where predicate:
if let element = array.first(where: { !$0.m }) {
print(element) // AW(day: 3, w: 32.01, m: false)
}
Note that it is Swift naming convention to name your structs starting with an uppercase letter. You should also use better descriptive naming.
CodePudding user response:
Map the items in an array of tuples with the property you want to count as key:
let mappedItems = array.map { ($0.m, 1) }
Then use this Dictionary
initializer to add the values if it finds duplicate keys.
let counts = Dictionary(mappedItems, uniquingKeysWith: )
this prints:
[true: 7, false: 3]
CodePudding user response:
Just in case if you’re interested. Below is the playground combine
version for @Leo Dabus answer.
var subscriptions = Set<AnyCancellable>()
struct aW: Hashable, Codable {
var day: Int
var w: Double
var m: Bool
}
let array = [
aW(day: 0, w: 32.62, m: true),
aW(day: 1, w: 32.40, m: true),
aW(day: 2, w: 32.16, m: true),
aW(day: 3, w: 32.01, m: false),
aW(day: 4, w: 31.81, m: true),
aW(day: 5, w: 31.61, m: false),
aW(day: 6, w: 31.41, m: false),
aW(day: 7, w: 31.20, m: true),
aW(day: 8, w: 31.01, m: true),
aW(day: 9, w: 30.83, m: true)].publisher
array
.reduce(0) {$1.m ? $0 : $0 1}
.sink(receiveValue: { print($0) }) // 3
.store(in: &subscriptions)