Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active September 21, 2019 13:29
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristopherjohnson/635e56dcc71842502fcd to your computer and use it in GitHub Desktop.
Save kristopherjohnson/635e56dcc71842502fcd to your computer and use it in GitHub Desktop.
Generic sum() and mean() extensions for Swift numeric collections
/// To use reduce() to sum a sequence, we need
///
/// - a zero (identity) element
/// - an addition operator
protocol Summable {
/// Identity element for this type and the + operation.
static var Zero: Self { get }
/// + operator must be defined for this type
func +(lhs: Self, rhs: Self) -> Self
}
extension SequenceType where Generator.Element: Summable {
/// Return sum of all values in the sequence
func sum() -> Generator.Element {
return self.reduce(Generator.Element.Zero, combine: +)
}
}
// Define Zero for Int, Double, and String so we can sum() them.
//
// Extend this to any other types for which you want to use sum().
extension Int: Summable {
/// The Int value 0
static var Zero: Int { return 0 }
}
extension Double: Summable {
/// The Double value 0.0
static var Zero: Double { return 0.0 }
}
extension String: Summable {
/// Empty string
static var Zero: String { return "" }
}
/// A generic mean() function requires that we be able
/// to convert values to Double.
protocol DoubleConvertible {
/// Return value as Double type
var doubleValue: Double { get }
}
// Define doubleValue() for Int and Double.
//
// Extend this to any other types for which you want
// to use mean().
extension Int: DoubleConvertible {
/// Return Int as Double
var doubleValue: Double { return Double(self) }
}
extension Double: DoubleConvertible {
/// Return Double value
var doubleValue: Double { return self }
}
extension CollectionType where
Generator.Element: DoubleConvertible,
Generator.Element: Summable,
Index.Distance: DoubleConvertible {
/// Return arithmetic mean of values in collection
func mean() -> Double {
assert(!self.isEmpty, "cannot calculate mean of empty collection")
return self.sum().doubleValue / self.count.doubleValue
}
}
// Examples
[1, 2, 3, 4, 5].sum() // 15
[1.1, 2.2, 3.3, 4.4, 5.5].sum() // 16.5
["a", "b", "c", "d", "e"].sum() // "abcde"
[1, 2, 3, 5].mean() // 2.75
[0.4, 1.2, 3.2].mean() // 1.6
@knguyen2708
Copy link

Awesome work man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment