Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active September 21, 2019 13:29
Show Gist options
  • Select an option

  • Save kristopherjohnson/635e56dcc71842502fcd to your computer and use it in GitHub Desktop.

Select an option

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
@mckrlx

mckrlx commented Apr 28, 2017

Copy link
Copy Markdown

Awesome work man!

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