diff --git a/README.md b/README.md index 4e57df8..a2df9db 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,30 @@ let countByResult = emails.countBy { (email) -> String in print(countByResult) // // ["gmail.com": 2, "yahoo.com": 1] ``` +#### Dictionary + +```swift +let userAges = ["Alice": 30, "Bob": 28, "Carlos": 30, "David": 28] + +let countByResult = userAges.countBy { (name, age) -> Int in + return age +} + +print(countByResult) // [28: 2, 30: 2] +``` + +#### Set + +```swift +let emails: Set = ["alice@gmail.com", "bob@yahoo.com", "carlos@gmail.com"] + +let countByResult = emails.countBy { (email) -> String in + return (email as! String).components(separatedBy: "@").last ?? "" +} + +print(countByResult) // ["gmail.com": 2, "yahoo.com": 1] +``` + ### `sum` The `sum` method returns the sum of all items in the collection. diff --git a/Sources/SwiftCollections/CountBy/DictionaryCountByExtensions.swift b/Sources/SwiftCollections/CountBy/DictionaryCountByExtensions.swift new file mode 100644 index 0000000..2189df4 --- /dev/null +++ b/Sources/SwiftCollections/CountBy/DictionaryCountByExtensions.swift @@ -0,0 +1,17 @@ +// +// DictionaryCountByExtensions.swift +// +// +// Created by R. Kukuh on 08/04/23. +// + +import Foundation + +public extension Dictionary { + func countBy(_ transform: (Key, Value) -> T) -> [T: Int] { + return reduce(into: [:]) { (counts, keyValue) in + let key = transform(keyValue.key, keyValue.value) + counts[key, default: 0] += 1 + } + } +} diff --git a/Sources/SwiftCollections/CountBy/SetCountByExtensions.swift b/Sources/SwiftCollections/CountBy/SetCountByExtensions.swift new file mode 100644 index 0000000..257f3fd --- /dev/null +++ b/Sources/SwiftCollections/CountBy/SetCountByExtensions.swift @@ -0,0 +1,17 @@ +// +// SetCountByExtensions.swift +// +// +// Created by R. Kukuh on 08/04/23. +// + +import Foundation + +public extension Set { + func countBy(_ transform: (Element) -> T) -> [T: Int] { + return reduce(into: [:]) { (counts, element) in + let key = transform(element) + counts[key, default: 0] += 1 + } + } +} diff --git a/Tests/SwiftCollectionsTests/CountBy/ArrayCountByTests.swift b/Tests/SwiftCollectionsTests/CountBy/ArrayCountByTests.swift index dd73a3e..88132df 100644 --- a/Tests/SwiftCollectionsTests/CountBy/ArrayCountByTests.swift +++ b/Tests/SwiftCollectionsTests/CountBy/ArrayCountByTests.swift @@ -20,6 +20,7 @@ class ArrayCountByTests: XCTestCase { func testArrayCountByClosure() { let emails = ["alice@gmail.com", "bob@yahoo.com", "carlos@gmail.com"] + let countByResult = emails.countBy { (email) -> String in return email.components(separatedBy: "@").last ?? "" } diff --git a/Tests/SwiftCollectionsTests/CountBy/DictionaryCountByTests.swift b/Tests/SwiftCollectionsTests/CountBy/DictionaryCountByTests.swift new file mode 100644 index 0000000..891b72f --- /dev/null +++ b/Tests/SwiftCollectionsTests/CountBy/DictionaryCountByTests.swift @@ -0,0 +1,21 @@ +// +// DictionaryCountByTests.swift +// +// +// Created by R. Kukuh on 08/04/23. +// + +import XCTest +@testable import SwiftCollections + +class DictionaryCountByClosureTests: XCTestCase { + func testDictionaryCountByClosure() { + let userAges = ["Alice": 30, "Bob": 28, "Carlos": 30, "David": 28] + let countByResult = userAges.countBy { (name, age) -> Int in + return age + } + + XCTAssertEqual(countByResult[30], 2, "The count for age '30' should be 2") + XCTAssertEqual(countByResult[28], 2, "The count for age '28' should be 2") + } +} diff --git a/Tests/SwiftCollectionsTests/CountBy/SetCountByTests.swift b/Tests/SwiftCollectionsTests/CountBy/SetCountByTests.swift new file mode 100644 index 0000000..0255368 --- /dev/null +++ b/Tests/SwiftCollectionsTests/CountBy/SetCountByTests.swift @@ -0,0 +1,22 @@ +// +// SetCountByTests.swift +// +// +// Created by R. Kukuh on 08/04/23. +// + +import XCTest +@testable import SwiftCollections + +class SetCountByClosureTests: XCTestCase { + func testSetCountByClosure() { + let emails: Set = ["alice@gmail.com", "bob@yahoo.com", "carlos@gmail.com"] + + let countByResult = emails.countBy { (email) -> String in + return (email as! String).components(separatedBy: "@").last ?? "" + } + + XCTAssertEqual(countByResult["gmail.com"], 2, "The count for 'gmail.com' should be 2") + XCTAssertEqual(countByResult["yahoo.com"], 1, "The count for 'yahoo.com' should be 1") + } +}