A functional tool-belt for Swift Language similar to Lo-Dash or Underscore.js in Javascript
See the codeDollar is a Swift library that provides useful functional programming helper methods without extending any built in objects. It is similar to Lo-Dash or Underscore.js in Javascript.
Cent is a library that extends certain Swift object types using the extension feature and gives its two cents to Swift language. It is now moved into a separate repo to support Swift Package Manager
NOTE: Starting Swift 4 $ is no longer a valid identifier. So you get the following error: '$' is not an identifier; use backticks to escape it . Instead use Dollar.
Add pod 'Dollar' to your Podfile and run pod install. Add use_frameworks! to the end of the Podfile. Also checkout this sample app.
Add the following dependency .Package(url: "https://github.com/ankurp/Dollar", majorVersion: 7, minor: 1) to your Package.swift file and then run swift build. Requires swift version 2.2 or greater that you can install from https://swift.org
git submodulegit submodule add https://github.com/ankurp/Dollar.git. If not using git download the project using git clone https://github.com/ankurp/Dollar.git in your project folder.Dollar folder. Drag Dollar.xcodeproj, inside the Dollar folder, into the file navigator of your Xcode project.import Dollar and you can call all of the helper functions.Still stuck. Then checkout this screencast on how to import
10.0.09.0.08.0.07.1.06.0.04.1.0 or 5.2.03.0.32.2.0Cocoa PodsSwift Package Managergit submoduledollar.swift.Dollar.atCreates an array of elements from the specified indexes, or keys, of the collection. Indexes may be specified as individual arguments or as arrays of indexes.
Dollar.at(["ant", "bat", "cat", "dog", "egg"], indexes: 0, 2, 4)
=> ["ant", "cat", "egg"]
Dollar.chunkCreates an array of elements split into groups the length of size. If array can’t be split evenly, the final chunk will be the remaining elements.
Dollar.chunk([1, 2, 3, 4], size: 2)
=> [[1, 2], [3, 4]]
Dollar.chunk([1, 2, 3, 4], size: 3)
=> [[1, 2, 3], [4]]
Dollar.compactCreates an array with all nil values removed.
Dollar.compact([3, nil, 4, 5])
=> [3, 4, 5]
Dollar.compact([nil, nil]) as NSObject[]
=> []
Dollar.containsChecks if a given value is present in the array.
Dollar.contains([1, 2, 3, 1, 2, 3], value: 2)
=> true
Dollar.contains([1, 2, 3, 1, 2, 3], value: 10)
=> false
Dollar.cycleCycles through the array definetly or indefinetly passing each element into the callback function. The second parameter is to specify how many times to cycle through the array. If left out it will cycle indefinetly.
Dollar.cycle([1, 2, 3], 2) {
print($0)
}
// Prints the following
123123
Dollar.differenceCreates an array excluding all values of the provided arrays
Dollar.difference([1, 2, 3, 4, 5], [5, 2, 10])
=> [1, 3, 4]
Dollar.eachPasses each element in the array to the callback
Dollar.each(["A", "B"]) {
print("Value \($0)")
}
=> ["A", "B"]
Dollar.each(["A", "B"]) { (index, elem) in
print("\(index) - \(elem)")
}
=> ["0 - A", "1 - B"]
Dollar.everyChecks if the given callback returns true value for all items in the array.
Dollar.every([1, 2, 3, 4], callback: { $0 < 20 })
=> true
Dollar.every([1, 2, 3, 4]) { $0 == 1 }
=> false
Dollar.factorialReturns factorial of integer
Dollar.factorial(3)
=> 6
Dollar.factorial(0)
=> 1
Dollar.fetchGet element from an array at the given index which can be negative to find elements from the end of the array. A default value can be returned if indexing out of bounds.
let arr = [1, 2, 3, 4, 5, 6, 7, 8]
Dollar.fetch(arr, 100)
=> nil
Dollar.fetch(arr, 100, orElse: 42)
=> 42
Dollar.fetch(arr, -1)
=> 8
Dollar.fillFills elements of array with value from start up to, but not including, end. This method mutates array.
var arr = Array<Int>(count: 5, repeatedValue: 1)
Dollar.fill(&arr, withElem: 42)
=> [42, 42, 42, 42, 42]
var arr = Array<Int>(count: 5, repeatedValue: 1)
Dollar.fill(&arr, withElem: 42, startIndex: 1, endIndex: 3)
=> [1, 42, 42, 42, 1]
Dollar.findIterates over elements of an array and returning the first element that the callback returns true for.
Dollar.find([1, 2, 3, 4], callback: { $0 == 2 })
=> 2
Dollar.find([1, 2, 3, 4]) { $0 == 10 }
=> nil
Dollar.findIndexThis method is like find except that it returns the index of the first element that passes the callback check.
let arr = [["age": 36], ["age": 40], ["age": 1]]
let result = Dollar.findIndex(arr) { $0["age"] < 20 }
result
=> 2
Dollar.findLastIndexThis method is like findIndex except that it iterates over elements of the array from right to left.
let arr = [["age": 36], ["age": 40], ["age": 1]]
let result = Dollar.findLastIndex(arr) { $0["age"] > 30 }
result
=> 1
Dollar.first(array: AnyObject[])Gets the first element in the array.
Dollar.first([1, 2, 3, 4])
=> 1
Dollar.first([])
=> nil
Dollar.groupByThis method returns a dictionary of values grouped by the value returned by a callback.
Dollar.groupBy([1, 2, 3, 4, 5], callback: {$0 % 2})
=> [0: [2, 4], 1: [1, 3]]
Dollar.groupBy(["strings", "with", "different", lengths"], callback: {$0.characters.count})
=> [7: ["strings", "lengths"], 9: ["different"], 4: ["With"]]
Dollar.second(array: AnyObject[])Gets the second element in the array.
Dollar.second([1, 2, 3, 4])
=> 2
Dollar.second([1])
=> nil
Dollar.second([])
=> nil
Dollar.flatMapMaps a function that converts elements to a list and then concatenates them.
let values = [2, 3, 4, 5, 6, 7]
Dollar.flatMap(values) { [$0, $0] }
=> [2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7]
Dollar.flatMapMaps a function that converts a type to an Optional over an Optional, and then returns a single-level Optional.
let url = NSURL(string: "https://apple.com/swift")
Dollar.flatMap(url) { $0.lastPathComponent }
=> Optional("swift")
Note: This is the same behavior as Optional chaining. The code above translates to
NSURL(string: "https://apple.com/swift/")?.lastPathComponent
=> Optional("swift")
Dollar.flattenFlattens a nested array of any depth.
Dollar.flatten([[3], 4, 5]) as Int[]
=> [3, 4, 5]
Dollar.flatten([[3], "Hello", 5]) as NSObject[]
=> [3, "Hello", 5]
Dollar.flatten([[[3], 4], 5]) as Int[]
=> [3, 4, 5]
Dollar.frequenciesThis method returns a dictionary of values in an array mapping to the total number of occurrences in the array. If passed a function it returns a frequency table of the results of the given function on the arrays elements.
Dollar.frequencies(["a", "a", "b", "c", "a", "b"])
=> ["a": 3, "b": 2, "c": 1]
Dollar.frequencies([1, 2, 3, 4, 5]) { $0 % 2 == 0 }
=> [false: 3, true: 2]
Dollar.gcdGCD function return greatest common denominator with number passed
Dollar.gcd(3, 10)
=> 1
Dollar.gcd(3, 9)
=> 3
Dollar.indexOfGets the index at which the first occurrence of value is found.
Dollar.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Dollar.indexOf(["A", "B", "C"], value: "B")
=> 1
Dollar.indexOf([3, 4, 5], value: 5)
=> 2
Dollar.indexOf([3, 4, 5], value: 3)
=> 0
Dollar.indexOf([3, 4, 5], value: 2)
=> nil
Dollar.initialGets all but the last element or last n elements of an array.
Dollar.initial([3, 4, 5])
=> [3, 4]
Dollar.initial([3, 4, 5], numElements: 2)
=> [3]
Dollar.intersectionCreates an array of unique values present in all provided arrays.
Dollar.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1])
=> [1, 2]
Dollar.it<T: Comparable>(i: T, isIn range: Range<T>)Returns true if i is in interval or range
Dollar.it("c", isIn: "a"..."z")
=> true
Dollar.it("z", isIn: "a"..<"z")
=> false
Dollar.it(1, isIn: -1.0...10.0)
=> true
Dollar.lastGets the last element from the array.
Dollar.last([3, 4, 5])
=> 5
Dollar.lastIndexOfGets the index at which the last occurrence of value is found.
Dollar.lastIndexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 4
Dollar.lcmLCM method return least common multiple with number passed
Dollar.lcm(3, 10)
=> 30
Dollar.lcm(3, 9)
=> 9
Dollar.restThe opposite of initial this method gets all but the first element or first n elements of an array.
Dollar.rest([3, 4, 5])
=> [4, 5]
Dollar.rest([3, 4, 5], numElements: 2)
=> [5]
Dollar.mapMaps each element to new value based on the map function passed
Dollar.map([1, 2, 3, 4]) {
$0 * 2
}
=> [2, 4, 6, 8]
Dollar.minRetrieves the minimum value in an array.
Dollar.min([2, 1, 2, 3, 4])
=> 1
Dollar.maxRetrieves the maximum value in an array.
Dollar.max([1, 2, 3, 4, 2, 1])
=> 4
Dollar.pluckRetrieves the value of a specified property from all elements in the array.
let arr = [["age": 20], ["age": 30], ["age": 40]]
Dollar.pluck(arr, value: "age")
=> [20, 30, 40]
Dollar.pullRemoves all provided values from the given array.
Dollar.pull([3, 4, 5, 3, 5], values: 3, 5)
=> [4]
Dollar.pull([3, 4, 5, 3, 5], values: 4)
=> [3, 5, 3, 5]
Dollar.pull([3, 4, 5, 3, 5], values: 3, 4, 5)
=> []
Dollar.pullAtRemoves all provided values from the given array at the given indices
let arr = [10, 20, 30, 40, 50]
Dollar.pullAt(arr, indices: 1, 2, 3)
Dollar.rangeCreates an array of numbers (positive and/or negative) progressing from start up to but not including end.
Dollar.range(4)
=> [0, 1, 2, 3]
Dollar.range(from: 1, to: 5)
=> [1, 2, 3, 4]
Dollar.range(from: 0, to: 20, incrementBy: 5)
=> [0, 5, 10, 15]
Dollar.range(from: 1, through: 5)
=> [1, 2, 3, 4, 5]
Dollar.range(from: 0, through: 20, incrementBy: 5)
=> [0, 5, 10, 15, 20]
Dollar.reduceReduce function that will resolve to one value after performing combine function on all elements
Dollar.reduce([1, 2, 3], initial: 0) { (total, element) in
total + element
}
=> 6
Dollar.sampleReturns a sample item from the array
let arr: [Int] = [2, 1, 2, 3, 4]
Dollar.contains(arr, value: Dollar.sample(arr))
=> true
Dollar.sequenceCreates an array of an arbitrary sequence. Especially useful with builtin ranges.
Dollar.sequence(0..4)
=> [0, 1, 2, 3]
Dollar.sequence(-2.0..2.0)
=> [-2.0, -1.0, 0.0, 1.0]
Dollar.sequence((0..20).by(5))
=> [0, 5, 10, 15]
Dollar.sequence("abc")
=> ["a", "b", "c"]
Dollar.removeRemoves an element from array.
Dollar.remove(["A", "B", "C", "D"], value: "B")
=> ["A", "C", "D"]
Dollar.removeRemoves all elements from an array that the callback returns true.
let result = Dollar.remove([1, 2, 3, 4, 5, 6]) {
$0 == 2 || $0 == 3
}
result
=> [1, 4, 5, 6]
Dollar.shuffleShuffles and returns the new shuffled array
let result = Dollar.shuffle([1, 2, 3, 4, 5, 6])
result
=> [4, 1, 3, 5, 6, 2]
Dollar.sizeReturns size of the array
Dollar.size(["a", "b", "c")
=> 3
Dollar.sortedIndexGives the smallest index at which a value should be inserted into a given the array is sorted.
Dollar.sortedIndex([3, 4, 6, 10], value: 5)
=> 2
Dollar.sortedIndex([10, 20, 30, 50], value: 40)
=> 3
Dollar.transposeCreates a tranposed matrix.
Dollar.transpose([[1, 2, 3], [4, 5, 6]])
=> [[1, 4], [2, 5], [3, 6]]
Dollar.unionCreates an array of unique values, in order, of the provided arrays.
Dollar.union([1, 2, 3], [5, 2, 1, 4], [2, 1])
=> [1, 2, 3, 5, 4]
Dollar.mergeCreates an array of all values, including duplicates, of the arrays in the order they are provided.
let arr = [1, 5]
let arr2 = [2, 4]
let arr3 = [5, 6]
let result = Dollar.merge(arr, arr2, arr3)
result
=> [1, 5, 2, 4, 5, 6]
Dollar.uniqCreates a duplicate-value-free version of an array.
Dollar.uniq([1, 2, 1, 3, 1])
=> [1, 2, 3]
Dollar.uniq([1, 2.5, 3, 1.5, 2, 3.5]) {
floor($0)
}
=> [1, 2.5, 3]
Dollar.withoutCreates an array excluding all provided values.
Dollar.without([3, 4, 5, 3, 5], values: 3, 5)
=> [4]
Dollar.without([3, 4, 5, 3, 5], values: 4)
=> [3, 5, 3, 5]
Dollar.without([3, 4, 5, 3, 5], values: 3, 4, 5)
=> []
Dollar.xorCreates an array that is the symmetric difference of the provided arrays.
Dollar.xor([1, 2, 3], [5, 2, 1, 4])
=> [3, 4, 5]
Dollar.zipCreates an array of grouped elements, the first of which contains the first elements of the given arrays.
Dollar.zip(["fred", "barney"], [30, 40], [true, false]) as [NSObject]
=> [["fred", 30, true], ["barney", 40, false]]
Dollar.zipObjectCreates an object composed from arrays of keys and values.
Dollar.zipObject(["fred", "barney"], values: [30, 40])
=> ["fred": 30, "barney": 40]
Dollar.partitionProduces an array of arrays, each containing n elements, each offset by step. Stops after a partition is less than n length.
let arr = [1, 2, 3, 4, 5]
Dollar.partition(arr, n: 2)
=> [[1, 2], [3, 4]]
Dollar.partition(arr, n: 4, step: 1)
=> [[1, 2, 3, 4], [2, 3, 4, 5]]
Dollar.partition(arr, n: 4, step: 1, pad: nil)
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5]]
Dollar.partition(arr, n: 4, step: 1, pad: [6, 7, 8])
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
Dollar.partitionAllProduces an array of arrays, each containing n elements, each offset by step. Continues after a partition is less than n length.
Dollar.partitionAll([1, 2, 3, 4, 5], n: 4, step: 1)
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5]]
Dollar.partitionByApplies a function to each element in array, splitting it each time the function returns a new value.
Dollar.partitionBy([1, 2, 3, 4, 5]) { $0 % 2 == 0 }
=> [[1], [2, 4], [3, 5], [6]]
Dollar.partitionBy([1, 7, 3, 6, 10, 12]) { $0 % 3 }
=> [[1, 7], [3, 6], [10], [12]]
Dollar.keysCreates an array of keys given a dictionary.
Dollar.keys(["Dog": 1, "Cat": 2])
=> ["Dog", "Cat"]
Dollar.valuesCreates an array of values given a dictionary
Dollar.values(["Dog": 1, "Cat": 2])
=> [1, 2]
Dollar.mergeMerges all of the dictionaries together and the latter dictionary overrides the value at a given key
let dict: Dictionary<String, Int> = ["Dog": 1, "Cat": 2]
let dict2: Dictionary<String, Int> = ["Cow": 3]
let dict3: Dictionary<String, Int> = ["Sheep": 4]
Dollar.merge(dict, dict2, dict3)
=> ["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4]
Dollar.pickCreates a shallow clone of a dictionary composed of the specified keys.
Dollar.pick(["Dog": 1, "Cat": 2, "Cow": 3], keys: "Dog", "Cow")
=> ["Dog": 1, "Cow": 3]
Dollar.omitCreates a shallow clone of a dictionary excluding the specified keys.
Dollar.omit(["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4], keys: "Cat", "Dog")
=> ["Cow": 3, "Sheep": 4]
Dollar.tapInvokes interceptor with the object and then returns object.
var beatle = Car(name: "Fusca")
Dollar.tap(beatle, {$0.name = "Beatle"}).color = "Blue"
Dollar.afterCreates a function that executes passed function only after being called n times.
var saves = ["profile", "settings"];
let asyncSave = { (function: () -> ()?) in
function()
// Saving right away for testing
// but in real world would be async
}
var isDone = false
var completeCallback = Dollar.after(saves.count) {
isDone = true
}
for elem in saves {
asyncSave(completeCallback)
}
isDone
=> true
Dollar.bindCreates a function that, when called, invokes func with the binding of arguments provided.
var helloWorldFunc = Dollar.bind({(T...) in
T[0] + " " + T[1] + " from " + T[2]
}, "Hello", "World", "Swift")
helloWorldFunc()
=> "Hello World from Swift"
helloWorldFunc = Dollar.bind({ $0 + " World" }, "Hello")
helloWorldFunc()
=> "Hello World"
helloWorldFunc = Dollar.bind({ $0 + $1 + " World" }, "Hello ", "Great")
helloWorldFunc()
=> "Hello Great World"
Dollar.composeCompose two or more functions where the return value of the first function is passed into the next function. Useful when chaining functions and returns a function that can be called with variadic argument values or an array of values as input
let double = { (params: Int...) -> [Int] in
return Dollar.map(params) { $0 * 2 }
}
let subtractTen = { (params: Int...) -> [Int] in
return Dollar.map(params) { $0 - 10 }
}
let doubleSubtractTen = Dollar.compose(double, subtractTen)
doubleSubtractTen(5, 6, 7)
=> [0, 2, 4]
let f = Dollar.compose({ (arr: [Int]) -> [Int] in
Dollar.map(arr) { $0 + 1 }
}, { (arr: [Int]) -> [Int] in
Dollar.map(arr) { $0 * 2 }
})
f([1, 2])
=> [4, 6]
Dollar.curryReturns a function which when invoked either executes the function returning its result, if all function arguments have been provided, or returns another function that accepts one more argument of the remaining function arguments until all arguments are supplied. This is useful for making partial function as seen in these examples.
func adder(x: Int, y: Int, z: Int) -> Int {
return x + y + z
}
let curriedAdder = Dollar.curry(adder)
let addTenAnd = curriedAdder(10)
let addThirtyAnd = addTenAnd(20)
addThirtyAnd(1)
=> 31
addThirtyAnd(50)
=> 80
addTenAnd(10)(10)
=> 30
Dollar.idThe identify function which simply returns the argument its given.
Dollar.id("Hello World from Swift")
=> "Hello World from Swift"
Dollar.memoizeReturns a memoized function to improve performance by caching recursive function values.
var times = 0 // to test memoization
let fibMemo = Dollar.memoize { (fib: (Int -> Int), val: Int) -> Int in
times += 1
return val == 1 || val == 0 ? 1 : fib(val - 1) + fib(val - 2)
}
let x = fibMemo(5)
times
=> 6
times = 0
let y = fibMemo(5)
times
=> 0
times = 0
let z = fibMemo(6)
times
=> 1
Dollar.noopA no-operation function.
Dollar.noop()
=> nil
Dollar.nowGets the number of seconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
Dollar.now()
=> 1431911564.292577
Dollar.onceGet a wrapper function that executes the passed function only once. Useful for getting shared config or creating singleton objects.
func createConfig() -> [String: String] {
var i = 1
return [
"App ID": "\(i++)",
"URL": "https://someurl"
]
}
let getConfig = Dollar.once(createConfig)
getConfig()
=> ["App ID": "1", "URL": "https://someurl"]
getConfig()
=> ["App ID": "1", "URL": "https://someurl"]
Dollar.partialCreates a function that, when called, invokes func with any additional partial arguments prepended to those provided to the new function.
let partialFunc = Dollar.partial({(T...) in
T[0] + " " + T[1] + " from " + T[2]
}, "Hello")
partialFunc("World", "Swift")
=> "Hello World from Swift"
Dollar.timesCall a function n times and also passes the index. If a value is returned in the function then the times method will return an array of those values.
let fun = Dollar.bind({ (names: String...) -> String in
let people = Dollar.join(names, separator: " from ")
return "Hello \(people)"
}, "Ankur", "Swift")
Dollar.times(2, function: fun) as String[]
=> ["Hello Ankur from Swift", "Hello Ankur from Swift"]
Dollar.chain(...)
anyReturns true if callback function returns true for at least one element in the array
var chain = Dollar.chain([1, 2, 3])
chain.any({ ($0 as Int) < 2 })
=> true
allReturns true if callback function returns true for all elements in the array
var chain = Dollar.chain([1, 2, 3])
chain.all({ ($0 as Int) < 10 })
=> true
eachPasses each element value to the callback function
var chain = Dollar.chain(["Hello", "World"])
var strBuilder = ""
chain.each({ strBuilder += ($0 as String) }).value
strBuilder
=> "HelloWorld"
filterFilters the arrary to elements for which the callback function returns true
var chain = Dollar.chain([1, 2, 3, 4])
chain.filter({ ($0 as Int) < 3 }).value
=> [1, 2]
firstReturns the first element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.first()
=> 1
secondReturns the second element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.second()
=> 2
thirdReturns the third element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.third()
=> 3
flattenFlattens a nested array of any depth.
var chain = Dollar.chain([[1, [2]], [3], 4])
chain.flatten().value
=> [1, 2, 3, 4]
initialGets all but the last element or last n elements of an array.
var chain = Dollar.chain([1, 2, 3, 4])
chain.initial(2).value
=> [1, 2]
mapMaps each element to the new value returned in the callback function
var chain = Dollar.chain([1, 2, 3, 4])
chain.map({ ($0 as Int) * 2 }).value
=> [2, 4, 6, 8]
sizeReturns size of the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.map({ ($0 as Int) * 2 }).size()
=> 4
sliceSlices the array based on the start and end position. If an end position is not specified it will slice till the end of the array.
var chain = Dollar.chain([1, 2, 3, 4, 5, 6, 7])
chain.slice(2, end: 4).value
=> [3, 4]
valueReturns the value after evaluating all callbacks
var chain = Dollar.chain([1, 2, 3, 4, 5, 6, 7])
chain.value
=> [1, 2, 3, 4, 5, 6, 7]
Chaining more than one method
Dollar.chain([[1, 2], 3, [[4], 5]])
.initial()
.flatten()
.first()
=> 1
Dollar.chain([1, 2, 3, 4, 5])
.filter { $0 % 1 == 0 }
.map { $0 * 2 }
.all { $0 < 10}
=> false
Dollar.chain([1, 2, 3, 4, 5])
.map { $0 * 2 }
.flatten()
.initial(2).value
=> [2, 4, 6]
<< elem: Element -> [Element]Overloaded operator to append element to an array or append elements from another array into the first array. Return array with the element appended in the end.
var array = [1, 2, 3]
array << 4
=> [1, 2, 3, 4]
array << [5, 6]
=> [1, 2, 3, 4, 5, 6]
at(indexes: Int...) -> [Element]Creates an array of elements from the specified indexes, or keys, of the collection.
let array = ["foo", "spam", "bar", "eggs"]
let some = array.at(1, 3)
=> ["spam", "eggs"]
each(callback: (Element) -> ()) -> [Element]For each item in the array invoke the callback by passing the elem
let array = ["foo", "spam", "bar", "eggs"]
array.each {
print($0)
}
=> ["foo", "spam", "bar", "eggs"]
eachWithIndex(callback: (Int, Element) -> ()) -> [Element]For each item in the array invoke the callback by passing the elem along with the index
let array = ["foo", "spam", "bar", "eggs"]
array.each { (index, elem)
print("\(index) - \(elem)")
}
=> ["foo", "spam", "bar", "eggs"]
cycle<U>(times: Int, callback: (Element) -> U)Cycles through the array definetly or indefinetly passing each element into the callback function. The second parameter is to specify how many times to cycle through the array. If left out it will cycle indefinetly.
[1, 2, 3].cycle(2) {
print($0)
}
// Prints the following
123123
[1, 2, 3].cycle {
print($0)
}
// Cycles in an infinite loop
every(callback: (Element) -> Bool) -> BoolChecks if the given callback returns true value for all items in the array.
["angry", "hungry"].every { (a: String) -> (Bool) in
a.hasSuffix("gry")
}
=> true
indexOf<T: Equatable>(value: T) -> IntGets the index at which the first occurrence of value is found.
let array = ["foo", "spam", "bar", "eggs"]
array.indexOf("spam")
=> 1
array.indexOf("None")
=> nil
fetch(index: Int, orElse: T? = .None) -> T!Get element from an array at the given index which can be negative to find elements from the end of the array. A default value can be returned if indexing out of bounds.
let arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr.fetch(100)
=> nil
arr.fetch(100, orElse: 42)
=> 42
arr.fetch(-1)
=> 8
findIndex(callback: (Element) -> Bool) -> Int?This method is like find except that it returns the index of the first element that passes the callback check.
let ind: int? = ["foo", "bar", "spam", "eggs"].findIndex {
$0.length == 4
}
ind! == 2
=> true
findLastIndex(callback: (Element) -> Bool) -> Int?This method is like findIndex except that it iterates over elements of the array from right to left.
let ind: int? = ["foo", "bar", "spam", "eggs"].findLastIndex {
$0.length == 4
}
ind! == 3
=> true
first() -> Element?Gets the first element in the array.
let first = ["foo", "bar"].first()
=> "foo"
flatten() -> [Element]Flattens a nested array of any depth.
let unFlattened = ["foo", ["bar"], [["spam"]], [[["eggs"]]] ]
let flattened = unFlattened.flatten()
=> ["foo", "bar", "spam", "eggs"]
get(index: Int) -> Element?Get element at index
let element = ["foo", "bar"].get(0)
element!
=> "foo"
let nothing = ["foo", "bar"].get(1000)
=> nil
initial(numElements: Int? = 1) -> [Element]Gets all but the last element or last n elements of an array.
let initial = ["foo", "bar", "spam"].initial(2)
=> ["foo"]
last() -> Element?Gets the last element from the array.
let last = ["foo", "bar"].last()
=> "bar"
rest(numElements: Int? = 1) -> [Element]The opposite of initial this method gets all but the first element or first n elements of an array.
let rest = ["foo", "bar", "spam"].rest(2)
=> ["spam"]
min<T: Comparable>() -> T?Retrieves the minimum value in an array.
let min = [ 0, 1, 2 ].min()
=> 0
max<T: Comparable>() -> T?Retrieves the maximum value in an array.
let max = [ 0, 1, 2].max()
=> 2
remove<T: Equatable>(value: T) -> T?Remove element from array
var arr = ["A", "B", "C", "D", "E"]
arr.remove("B")
=> ["A", "C", "D", "E"]
contains<T:Equatable>(value: T) -> BoolChecks if a given value is present in the array.
var arr = ["A", "B", "C", "D", "E"]
arr.contains("C")
=> true
arr.contains("Z")
=> false
"A".description -> StringGet string description of Character
let ch: Character = "A"
let str = ch.description
=> "A"
"A".ord -> IntGet int representation of character
Character("A").ord
=> 65
Date.from(#year: Int, month: Int, day: Int) -> NSDateReturns a new Date given the year month and day
let date = Date.from(2014, 1, 1)
=> "Jan 1, 2014, 12:00 AM"
Date.from(#unix: Double) -> NSDateReturns a new Date given the unix timestamp (timeIntervalSince1970)
let date = Date.from(unix: 1_388_552_400.0)
=> "Jan 1, 2014, 12:00 AM"
Date.parse(dateStr: String, format: String = "yyyy-MM-dd") -> NSDateParses the date based on the format and return a new Date
let parsedDate = Date.parse("2014-01-01", format: "yyyy-MM-dd")
=> "Jan 1, 2014, 12:00 AM"
Date.unix(date: NSDate = NSDate()) -> DoubleReturns the unix timestamp of the date passed in or the current unix timestamp
let currentUnix = Date.unix()
=> 1,388,552,400.0
var otherNSDate = Date()
let otherUnix = Date.unix(otherDate)
=> 1,388,552,400.0
Int.hour.fromNow et al.Use the following syntax to calculate dates and times based on the user's current calendar.
1.day.ago
=> "Apr 10, 2015, 11:51 AM"
4.hours.fromNow
=> "Apr 11, 2015, 3:51 PM"
merge<K, V>(dictionaries: Dictionary<K, V>...)Merges the dictionary with dictionaries passed. The latter dictionaries will override values of the keys that are already set
var dic = ["foo": "bar"]
let anotherDic = ["foo": "baz", "spam": "eggs"]
dic.merge(anotherDic)
=> ["foo": "baz", "spam": "eggs"]
times(callback: (Int) -> ())Invoke a callback n times with callback that takes index
5.times { print("Na") }
=> "NaNaNaNaNa"
times (function: () -> ())Invoke a callback n times
5.times { (a: Int) -> () in print("\(a) ") }
=> 0 1 2 3 4
char -> CharacterGet ASCII character from integer
65.char
=> "A"
isEvenCheck if int is even
2.isEven
=> true
1.isEven
=> false
isOddCheck if int is odd
3.isOdd
=> true
2.isOdd
=> false
digits() -> [Int]Splits the int into array of digits
4208.digits()
=> [4, 2, 0, 8]
lcm() -> IntLCM method return least common multiple with number passed
3.lcm(10)
=> 30
3.lcm(9)
=> 9
gcd() -> IntGCD method return greatest common denominator with number passed
3.gcd(10)
=> 1
3.gcd(9)
=> 3
random() -> IntReturns random number from 0 upto but not including value of integer
3.random()
=> 2
3.random()
=> 1
factorial() -> IntReturns factorial of integer
3.factorial()
=> 6
0.factorial()
=> 1
isIn(interval) -> BoolReturns true if i is in interval or range
5.isIn(1...10)
=> true
10.isIn(1..<10)
=> false
next() -> IntGet the next int
10.next()
=> 11
prev() -> IntGet the previous int
10.prev()
=> 9
upTo(limit: Int, callback: () -> ())Invoke the callback from int up to and including limit
3.upTo(5) {
print("Hi")
}
Prints "HiHiHi"
downTo(limit: Int, callback: () -> ())Invoke the callback from int down to and including limit
3.downTo(0) {
print("Hi")
}
Prints "HiHiHiHi"
.lengthGet the length of the string
"Hello".length
=> 5
.camelCaseGet the camel case representation of the string
"__Dollar and cent-- dollarANDCent".camelCase
=> "dollarAndCentDollarAndCent"
.kebabCaseGet the kebab case representation of the string
"__Dollar and cent-- dollarANDCent".kebabCase
=> "dollar-and-cent-dollar-and-cent"
.snakeCaseGet the snake case representation of the string
"__Dollar and cent-- dollarANDCent".snakeCase
=> "dollar_and_cent_dollar_and_cent"
.startCaseGet the start case representation of the string
"__Dollar and cent-- dollarANDCent".startCase
=> "Dollar And Cent Dollar And Cent"
=~ str: String -> BoolDoes a regex match of whether regex string on the right is matches the string on the left
"Dollar" =~ "oll"
=> true
* n: Int -> StringGet string concatenated n times
"Hi Swift! " * 3
=> "Hi Swift! Hi Swift! Hi Swift! "
[i: Int] -> Character?Get character at a subscript
"Hello World"[6] == "W"
=> true
"Hi"[5]
=> nil
[str: String] -> String?Returns the substring based on the first regex match passed in the subscript
let proj = "Dollar and Cent"
proj["^.+[^and Cent]"]
=> {Some: "Dollar"}
[r: Range<Int>] -> StringGet substring using subscript notation and by passing a range
"Hello World"[0..<5] == "Hello"
=> true
indexOf(char: Character) -> Int?Get the start index of character
"hello world".indexOf(Character("o"))!
=> 4
indexOf(str: String) -> Int?Get the start index of string
"hello world".indexOf("llo")!
=> 2
"hello world".indexOf("illo")
=> nil
indexOf(pattern: String) -> Int?Get the start index of regex pattern inside the string
"hello world".indexOf(".llo")!
=> 1
split(delimiter: Character) -> [String]Get an array from string split using the delimiter character
"Hello World".split(" ")
=> ["Hello", "World"]
lstrip() -> StringGet string without leading spaces
let leadingSpace = " Hello"
leadingSpace.lstrip()
=> "Hello"
rstrip() -> StringGet string without trailing spaces
let trailingSpace = "Hello "
trailingSpace.rstrip()
=> "Hello"
strip() -> StringGet string without leading or trailing spaces
let spaces = " Hello "
spaces.strip()
=> "Hello"
initInit with regex pattern as string
Regex.init("^Hello.World$") // Regex that matches "Hello World"
matches(testStr: String) -> [AnyObject]Return matches based on String passed.
let re = Regex.init("^Hello.World$")
re.matches("Hello World")
test(testStr: String) -> Boollet re = Regex.init("^Hello.World$")
re.test("Hello World")
=> true
re.test("Str")
=> false
escapeStr(str: String) -> StringEscape string with regex characters
Regex.escape("Hello.World")
=> "Hello\.World"
==Check the equality of two ranges
(1...5) == (1...5)
=> true
(1..<5) == (1...5)
=> false
eachWithIndex(callback: (T) -> ())For each index in the range invoke the callback by passing the item in range
(1...5).eachWithIndex { (a: Int) -> () in print("\(a)") }
=> 12345
each(callback: () -> ())For each index in the range invoke the callback
(1...5).each { print("Na") }
=> "NaNaNaNaNa"
If you are interested in contributing checkout CONTRIBUTING.md
6,173 followers · starred Jun 2014
156 followers · starred Nov 2015
1,590 followers · starred Aug 2021
188 followers · starred Oct 2014
A functional tool-belt for Swift Language similar to Lo-Dash or Underscore.js in Javascript
See the codeDollar is a Swift library that provides useful functional programming helper methods without extending any built in objects. It is similar to Lo-Dash or Underscore.js in Javascript.
Cent is a library that extends certain Swift object types using the extension feature and gives its two cents to Swift language. It is now moved into a separate repo to support Swift Package Manager
NOTE: Starting Swift 4 $ is no longer a valid identifier. So you get the following error: '$' is not an identifier; use backticks to escape it . Instead use Dollar.
Add pod 'Dollar' to your Podfile and run pod install. Add use_frameworks! to the end of the Podfile. Also checkout this sample app.
Add the following dependency .Package(url: "https://github.com/ankurp/Dollar", majorVersion: 7, minor: 1) to your Package.swift file and then run swift build. Requires swift version 2.2 or greater that you can install from https://swift.org
git submodulegit submodule add https://github.com/ankurp/Dollar.git. If not using git download the project using git clone https://github.com/ankurp/Dollar.git in your project folder.Dollar folder. Drag Dollar.xcodeproj, inside the Dollar folder, into the file navigator of your Xcode project.import Dollar and you can call all of the helper functions.Still stuck. Then checkout this screencast on how to import
10.0.09.0.08.0.07.1.06.0.04.1.0 or 5.2.03.0.32.2.0Cocoa PodsSwift Package Managergit submoduledollar.swift.Dollar.atCreates an array of elements from the specified indexes, or keys, of the collection. Indexes may be specified as individual arguments or as arrays of indexes.
Dollar.at(["ant", "bat", "cat", "dog", "egg"], indexes: 0, 2, 4)
=> ["ant", "cat", "egg"]
Dollar.chunkCreates an array of elements split into groups the length of size. If array can’t be split evenly, the final chunk will be the remaining elements.
Dollar.chunk([1, 2, 3, 4], size: 2)
=> [[1, 2], [3, 4]]
Dollar.chunk([1, 2, 3, 4], size: 3)
=> [[1, 2, 3], [4]]
Dollar.compactCreates an array with all nil values removed.
Dollar.compact([3, nil, 4, 5])
=> [3, 4, 5]
Dollar.compact([nil, nil]) as NSObject[]
=> []
Dollar.containsChecks if a given value is present in the array.
Dollar.contains([1, 2, 3, 1, 2, 3], value: 2)
=> true
Dollar.contains([1, 2, 3, 1, 2, 3], value: 10)
=> false
Dollar.cycleCycles through the array definetly or indefinetly passing each element into the callback function. The second parameter is to specify how many times to cycle through the array. If left out it will cycle indefinetly.
Dollar.cycle([1, 2, 3], 2) {
print($0)
}
// Prints the following
123123
Dollar.differenceCreates an array excluding all values of the provided arrays
Dollar.difference([1, 2, 3, 4, 5], [5, 2, 10])
=> [1, 3, 4]
Dollar.eachPasses each element in the array to the callback
Dollar.each(["A", "B"]) {
print("Value \($0)")
}
=> ["A", "B"]
Dollar.each(["A", "B"]) { (index, elem) in
print("\(index) - \(elem)")
}
=> ["0 - A", "1 - B"]
Dollar.everyChecks if the given callback returns true value for all items in the array.
Dollar.every([1, 2, 3, 4], callback: { $0 < 20 })
=> true
Dollar.every([1, 2, 3, 4]) { $0 == 1 }
=> false
Dollar.factorialReturns factorial of integer
Dollar.factorial(3)
=> 6
Dollar.factorial(0)
=> 1
Dollar.fetchGet element from an array at the given index which can be negative to find elements from the end of the array. A default value can be returned if indexing out of bounds.
let arr = [1, 2, 3, 4, 5, 6, 7, 8]
Dollar.fetch(arr, 100)
=> nil
Dollar.fetch(arr, 100, orElse: 42)
=> 42
Dollar.fetch(arr, -1)
=> 8
Dollar.fillFills elements of array with value from start up to, but not including, end. This method mutates array.
var arr = Array<Int>(count: 5, repeatedValue: 1)
Dollar.fill(&arr, withElem: 42)
=> [42, 42, 42, 42, 42]
var arr = Array<Int>(count: 5, repeatedValue: 1)
Dollar.fill(&arr, withElem: 42, startIndex: 1, endIndex: 3)
=> [1, 42, 42, 42, 1]
Dollar.findIterates over elements of an array and returning the first element that the callback returns true for.
Dollar.find([1, 2, 3, 4], callback: { $0 == 2 })
=> 2
Dollar.find([1, 2, 3, 4]) { $0 == 10 }
=> nil
Dollar.findIndexThis method is like find except that it returns the index of the first element that passes the callback check.
let arr = [["age": 36], ["age": 40], ["age": 1]]
let result = Dollar.findIndex(arr) { $0["age"] < 20 }
result
=> 2
Dollar.findLastIndexThis method is like findIndex except that it iterates over elements of the array from right to left.
let arr = [["age": 36], ["age": 40], ["age": 1]]
let result = Dollar.findLastIndex(arr) { $0["age"] > 30 }
result
=> 1
Dollar.first(array: AnyObject[])Gets the first element in the array.
Dollar.first([1, 2, 3, 4])
=> 1
Dollar.first([])
=> nil
Dollar.groupByThis method returns a dictionary of values grouped by the value returned by a callback.
Dollar.groupBy([1, 2, 3, 4, 5], callback: {$0 % 2})
=> [0: [2, 4], 1: [1, 3]]
Dollar.groupBy(["strings", "with", "different", lengths"], callback: {$0.characters.count})
=> [7: ["strings", "lengths"], 9: ["different"], 4: ["With"]]
Dollar.second(array: AnyObject[])Gets the second element in the array.
Dollar.second([1, 2, 3, 4])
=> 2
Dollar.second([1])
=> nil
Dollar.second([])
=> nil
Dollar.flatMapMaps a function that converts elements to a list and then concatenates them.
let values = [2, 3, 4, 5, 6, 7]
Dollar.flatMap(values) { [$0, $0] }
=> [2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7]
Dollar.flatMapMaps a function that converts a type to an Optional over an Optional, and then returns a single-level Optional.
let url = NSURL(string: "https://apple.com/swift")
Dollar.flatMap(url) { $0.lastPathComponent }
=> Optional("swift")
Note: This is the same behavior as Optional chaining. The code above translates to
NSURL(string: "https://apple.com/swift/")?.lastPathComponent
=> Optional("swift")
Dollar.flattenFlattens a nested array of any depth.
Dollar.flatten([[3], 4, 5]) as Int[]
=> [3, 4, 5]
Dollar.flatten([[3], "Hello", 5]) as NSObject[]
=> [3, "Hello", 5]
Dollar.flatten([[[3], 4], 5]) as Int[]
=> [3, 4, 5]
Dollar.frequenciesThis method returns a dictionary of values in an array mapping to the total number of occurrences in the array. If passed a function it returns a frequency table of the results of the given function on the arrays elements.
Dollar.frequencies(["a", "a", "b", "c", "a", "b"])
=> ["a": 3, "b": 2, "c": 1]
Dollar.frequencies([1, 2, 3, 4, 5]) { $0 % 2 == 0 }
=> [false: 3, true: 2]
Dollar.gcdGCD function return greatest common denominator with number passed
Dollar.gcd(3, 10)
=> 1
Dollar.gcd(3, 9)
=> 3
Dollar.indexOfGets the index at which the first occurrence of value is found.
Dollar.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Dollar.indexOf(["A", "B", "C"], value: "B")
=> 1
Dollar.indexOf([3, 4, 5], value: 5)
=> 2
Dollar.indexOf([3, 4, 5], value: 3)
=> 0
Dollar.indexOf([3, 4, 5], value: 2)
=> nil
Dollar.initialGets all but the last element or last n elements of an array.
Dollar.initial([3, 4, 5])
=> [3, 4]
Dollar.initial([3, 4, 5], numElements: 2)
=> [3]
Dollar.intersectionCreates an array of unique values present in all provided arrays.
Dollar.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1])
=> [1, 2]
Dollar.it<T: Comparable>(i: T, isIn range: Range<T>)Returns true if i is in interval or range
Dollar.it("c", isIn: "a"..."z")
=> true
Dollar.it("z", isIn: "a"..<"z")
=> false
Dollar.it(1, isIn: -1.0...10.0)
=> true
Dollar.lastGets the last element from the array.
Dollar.last([3, 4, 5])
=> 5
Dollar.lastIndexOfGets the index at which the last occurrence of value is found.
Dollar.lastIndexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 4
Dollar.lcmLCM method return least common multiple with number passed
Dollar.lcm(3, 10)
=> 30
Dollar.lcm(3, 9)
=> 9
Dollar.restThe opposite of initial this method gets all but the first element or first n elements of an array.
Dollar.rest([3, 4, 5])
=> [4, 5]
Dollar.rest([3, 4, 5], numElements: 2)
=> [5]
Dollar.mapMaps each element to new value based on the map function passed
Dollar.map([1, 2, 3, 4]) {
$0 * 2
}
=> [2, 4, 6, 8]
Dollar.minRetrieves the minimum value in an array.
Dollar.min([2, 1, 2, 3, 4])
=> 1
Dollar.maxRetrieves the maximum value in an array.
Dollar.max([1, 2, 3, 4, 2, 1])
=> 4
Dollar.pluckRetrieves the value of a specified property from all elements in the array.
let arr = [["age": 20], ["age": 30], ["age": 40]]
Dollar.pluck(arr, value: "age")
=> [20, 30, 40]
Dollar.pullRemoves all provided values from the given array.
Dollar.pull([3, 4, 5, 3, 5], values: 3, 5)
=> [4]
Dollar.pull([3, 4, 5, 3, 5], values: 4)
=> [3, 5, 3, 5]
Dollar.pull([3, 4, 5, 3, 5], values: 3, 4, 5)
=> []
Dollar.pullAtRemoves all provided values from the given array at the given indices
let arr = [10, 20, 30, 40, 50]
Dollar.pullAt(arr, indices: 1, 2, 3)
Dollar.rangeCreates an array of numbers (positive and/or negative) progressing from start up to but not including end.
Dollar.range(4)
=> [0, 1, 2, 3]
Dollar.range(from: 1, to: 5)
=> [1, 2, 3, 4]
Dollar.range(from: 0, to: 20, incrementBy: 5)
=> [0, 5, 10, 15]
Dollar.range(from: 1, through: 5)
=> [1, 2, 3, 4, 5]
Dollar.range(from: 0, through: 20, incrementBy: 5)
=> [0, 5, 10, 15, 20]
Dollar.reduceReduce function that will resolve to one value after performing combine function on all elements
Dollar.reduce([1, 2, 3], initial: 0) { (total, element) in
total + element
}
=> 6
Dollar.sampleReturns a sample item from the array
let arr: [Int] = [2, 1, 2, 3, 4]
Dollar.contains(arr, value: Dollar.sample(arr))
=> true
Dollar.sequenceCreates an array of an arbitrary sequence. Especially useful with builtin ranges.
Dollar.sequence(0..4)
=> [0, 1, 2, 3]
Dollar.sequence(-2.0..2.0)
=> [-2.0, -1.0, 0.0, 1.0]
Dollar.sequence((0..20).by(5))
=> [0, 5, 10, 15]
Dollar.sequence("abc")
=> ["a", "b", "c"]
Dollar.removeRemoves an element from array.
Dollar.remove(["A", "B", "C", "D"], value: "B")
=> ["A", "C", "D"]
Dollar.removeRemoves all elements from an array that the callback returns true.
let result = Dollar.remove([1, 2, 3, 4, 5, 6]) {
$0 == 2 || $0 == 3
}
result
=> [1, 4, 5, 6]
Dollar.shuffleShuffles and returns the new shuffled array
let result = Dollar.shuffle([1, 2, 3, 4, 5, 6])
result
=> [4, 1, 3, 5, 6, 2]
Dollar.sizeReturns size of the array
Dollar.size(["a", "b", "c")
=> 3
Dollar.sortedIndexGives the smallest index at which a value should be inserted into a given the array is sorted.
Dollar.sortedIndex([3, 4, 6, 10], value: 5)
=> 2
Dollar.sortedIndex([10, 20, 30, 50], value: 40)
=> 3
Dollar.transposeCreates a tranposed matrix.
Dollar.transpose([[1, 2, 3], [4, 5, 6]])
=> [[1, 4], [2, 5], [3, 6]]
Dollar.unionCreates an array of unique values, in order, of the provided arrays.
Dollar.union([1, 2, 3], [5, 2, 1, 4], [2, 1])
=> [1, 2, 3, 5, 4]
Dollar.mergeCreates an array of all values, including duplicates, of the arrays in the order they are provided.
let arr = [1, 5]
let arr2 = [2, 4]
let arr3 = [5, 6]
let result = Dollar.merge(arr, arr2, arr3)
result
=> [1, 5, 2, 4, 5, 6]
Dollar.uniqCreates a duplicate-value-free version of an array.
Dollar.uniq([1, 2, 1, 3, 1])
=> [1, 2, 3]
Dollar.uniq([1, 2.5, 3, 1.5, 2, 3.5]) {
floor($0)
}
=> [1, 2.5, 3]
Dollar.withoutCreates an array excluding all provided values.
Dollar.without([3, 4, 5, 3, 5], values: 3, 5)
=> [4]
Dollar.without([3, 4, 5, 3, 5], values: 4)
=> [3, 5, 3, 5]
Dollar.without([3, 4, 5, 3, 5], values: 3, 4, 5)
=> []
Dollar.xorCreates an array that is the symmetric difference of the provided arrays.
Dollar.xor([1, 2, 3], [5, 2, 1, 4])
=> [3, 4, 5]
Dollar.zipCreates an array of grouped elements, the first of which contains the first elements of the given arrays.
Dollar.zip(["fred", "barney"], [30, 40], [true, false]) as [NSObject]
=> [["fred", 30, true], ["barney", 40, false]]
Dollar.zipObjectCreates an object composed from arrays of keys and values.
Dollar.zipObject(["fred", "barney"], values: [30, 40])
=> ["fred": 30, "barney": 40]
Dollar.partitionProduces an array of arrays, each containing n elements, each offset by step. Stops after a partition is less than n length.
let arr = [1, 2, 3, 4, 5]
Dollar.partition(arr, n: 2)
=> [[1, 2], [3, 4]]
Dollar.partition(arr, n: 4, step: 1)
=> [[1, 2, 3, 4], [2, 3, 4, 5]]
Dollar.partition(arr, n: 4, step: 1, pad: nil)
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5]]
Dollar.partition(arr, n: 4, step: 1, pad: [6, 7, 8])
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
Dollar.partitionAllProduces an array of arrays, each containing n elements, each offset by step. Continues after a partition is less than n length.
Dollar.partitionAll([1, 2, 3, 4, 5], n: 4, step: 1)
=> [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5]]
Dollar.partitionByApplies a function to each element in array, splitting it each time the function returns a new value.
Dollar.partitionBy([1, 2, 3, 4, 5]) { $0 % 2 == 0 }
=> [[1], [2, 4], [3, 5], [6]]
Dollar.partitionBy([1, 7, 3, 6, 10, 12]) { $0 % 3 }
=> [[1, 7], [3, 6], [10], [12]]
Dollar.keysCreates an array of keys given a dictionary.
Dollar.keys(["Dog": 1, "Cat": 2])
=> ["Dog", "Cat"]
Dollar.valuesCreates an array of values given a dictionary
Dollar.values(["Dog": 1, "Cat": 2])
=> [1, 2]
Dollar.mergeMerges all of the dictionaries together and the latter dictionary overrides the value at a given key
let dict: Dictionary<String, Int> = ["Dog": 1, "Cat": 2]
let dict2: Dictionary<String, Int> = ["Cow": 3]
let dict3: Dictionary<String, Int> = ["Sheep": 4]
Dollar.merge(dict, dict2, dict3)
=> ["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4]
Dollar.pickCreates a shallow clone of a dictionary composed of the specified keys.
Dollar.pick(["Dog": 1, "Cat": 2, "Cow": 3], keys: "Dog", "Cow")
=> ["Dog": 1, "Cow": 3]
Dollar.omitCreates a shallow clone of a dictionary excluding the specified keys.
Dollar.omit(["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4], keys: "Cat", "Dog")
=> ["Cow": 3, "Sheep": 4]
Dollar.tapInvokes interceptor with the object and then returns object.
var beatle = Car(name: "Fusca")
Dollar.tap(beatle, {$0.name = "Beatle"}).color = "Blue"
Dollar.afterCreates a function that executes passed function only after being called n times.
var saves = ["profile", "settings"];
let asyncSave = { (function: () -> ()?) in
function()
// Saving right away for testing
// but in real world would be async
}
var isDone = false
var completeCallback = Dollar.after(saves.count) {
isDone = true
}
for elem in saves {
asyncSave(completeCallback)
}
isDone
=> true
Dollar.bindCreates a function that, when called, invokes func with the binding of arguments provided.
var helloWorldFunc = Dollar.bind({(T...) in
T[0] + " " + T[1] + " from " + T[2]
}, "Hello", "World", "Swift")
helloWorldFunc()
=> "Hello World from Swift"
helloWorldFunc = Dollar.bind({ $0 + " World" }, "Hello")
helloWorldFunc()
=> "Hello World"
helloWorldFunc = Dollar.bind({ $0 + $1 + " World" }, "Hello ", "Great")
helloWorldFunc()
=> "Hello Great World"
Dollar.composeCompose two or more functions where the return value of the first function is passed into the next function. Useful when chaining functions and returns a function that can be called with variadic argument values or an array of values as input
let double = { (params: Int...) -> [Int] in
return Dollar.map(params) { $0 * 2 }
}
let subtractTen = { (params: Int...) -> [Int] in
return Dollar.map(params) { $0 - 10 }
}
let doubleSubtractTen = Dollar.compose(double, subtractTen)
doubleSubtractTen(5, 6, 7)
=> [0, 2, 4]
let f = Dollar.compose({ (arr: [Int]) -> [Int] in
Dollar.map(arr) { $0 + 1 }
}, { (arr: [Int]) -> [Int] in
Dollar.map(arr) { $0 * 2 }
})
f([1, 2])
=> [4, 6]
Dollar.curryReturns a function which when invoked either executes the function returning its result, if all function arguments have been provided, or returns another function that accepts one more argument of the remaining function arguments until all arguments are supplied. This is useful for making partial function as seen in these examples.
func adder(x: Int, y: Int, z: Int) -> Int {
return x + y + z
}
let curriedAdder = Dollar.curry(adder)
let addTenAnd = curriedAdder(10)
let addThirtyAnd = addTenAnd(20)
addThirtyAnd(1)
=> 31
addThirtyAnd(50)
=> 80
addTenAnd(10)(10)
=> 30
Dollar.idThe identify function which simply returns the argument its given.
Dollar.id("Hello World from Swift")
=> "Hello World from Swift"
Dollar.memoizeReturns a memoized function to improve performance by caching recursive function values.
var times = 0 // to test memoization
let fibMemo = Dollar.memoize { (fib: (Int -> Int), val: Int) -> Int in
times += 1
return val == 1 || val == 0 ? 1 : fib(val - 1) + fib(val - 2)
}
let x = fibMemo(5)
times
=> 6
times = 0
let y = fibMemo(5)
times
=> 0
times = 0
let z = fibMemo(6)
times
=> 1
Dollar.noopA no-operation function.
Dollar.noop()
=> nil
Dollar.nowGets the number of seconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
Dollar.now()
=> 1431911564.292577
Dollar.onceGet a wrapper function that executes the passed function only once. Useful for getting shared config or creating singleton objects.
func createConfig() -> [String: String] {
var i = 1
return [
"App ID": "\(i++)",
"URL": "https://someurl"
]
}
let getConfig = Dollar.once(createConfig)
getConfig()
=> ["App ID": "1", "URL": "https://someurl"]
getConfig()
=> ["App ID": "1", "URL": "https://someurl"]
Dollar.partialCreates a function that, when called, invokes func with any additional partial arguments prepended to those provided to the new function.
let partialFunc = Dollar.partial({(T...) in
T[0] + " " + T[1] + " from " + T[2]
}, "Hello")
partialFunc("World", "Swift")
=> "Hello World from Swift"
Dollar.timesCall a function n times and also passes the index. If a value is returned in the function then the times method will return an array of those values.
let fun = Dollar.bind({ (names: String...) -> String in
let people = Dollar.join(names, separator: " from ")
return "Hello \(people)"
}, "Ankur", "Swift")
Dollar.times(2, function: fun) as String[]
=> ["Hello Ankur from Swift", "Hello Ankur from Swift"]
Dollar.chain(...)
anyReturns true if callback function returns true for at least one element in the array
var chain = Dollar.chain([1, 2, 3])
chain.any({ ($0 as Int) < 2 })
=> true
allReturns true if callback function returns true for all elements in the array
var chain = Dollar.chain([1, 2, 3])
chain.all({ ($0 as Int) < 10 })
=> true
eachPasses each element value to the callback function
var chain = Dollar.chain(["Hello", "World"])
var strBuilder = ""
chain.each({ strBuilder += ($0 as String) }).value
strBuilder
=> "HelloWorld"
filterFilters the arrary to elements for which the callback function returns true
var chain = Dollar.chain([1, 2, 3, 4])
chain.filter({ ($0 as Int) < 3 }).value
=> [1, 2]
firstReturns the first element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.first()
=> 1
secondReturns the second element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.second()
=> 2
thirdReturns the third element in the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.third()
=> 3
flattenFlattens a nested array of any depth.
var chain = Dollar.chain([[1, [2]], [3], 4])
chain.flatten().value
=> [1, 2, 3, 4]
initialGets all but the last element or last n elements of an array.
var chain = Dollar.chain([1, 2, 3, 4])
chain.initial(2).value
=> [1, 2]
mapMaps each element to the new value returned in the callback function
var chain = Dollar.chain([1, 2, 3, 4])
chain.map({ ($0 as Int) * 2 }).value
=> [2, 4, 6, 8]
sizeReturns size of the array and terminates the chain
var chain = Dollar.chain([1, 2, 3, 4])
chain.map({ ($0 as Int) * 2 }).size()
=> 4
sliceSlices the array based on the start and end position. If an end position is not specified it will slice till the end of the array.
var chain = Dollar.chain([1, 2, 3, 4, 5, 6, 7])
chain.slice(2, end: 4).value
=> [3, 4]
valueReturns the value after evaluating all callbacks
var chain = Dollar.chain([1, 2, 3, 4, 5, 6, 7])
chain.value
=> [1, 2, 3, 4, 5, 6, 7]
Chaining more than one method
Dollar.chain([[1, 2], 3, [[4], 5]])
.initial()
.flatten()
.first()
=> 1
Dollar.chain([1, 2, 3, 4, 5])
.filter { $0 % 1 == 0 }
.map { $0 * 2 }
.all { $0 < 10}
=> false
Dollar.chain([1, 2, 3, 4, 5])
.map { $0 * 2 }
.flatten()
.initial(2).value
=> [2, 4, 6]
<< elem: Element -> [Element]Overloaded operator to append element to an array or append elements from another array into the first array. Return array with the element appended in the end.
var array = [1, 2, 3]
array << 4
=> [1, 2, 3, 4]
array << [5, 6]
=> [1, 2, 3, 4, 5, 6]
at(indexes: Int...) -> [Element]Creates an array of elements from the specified indexes, or keys, of the collection.
let array = ["foo", "spam", "bar", "eggs"]
let some = array.at(1, 3)
=> ["spam", "eggs"]
each(callback: (Element) -> ()) -> [Element]For each item in the array invoke the callback by passing the elem
let array = ["foo", "spam", "bar", "eggs"]
array.each {
print($0)
}
=> ["foo", "spam", "bar", "eggs"]
eachWithIndex(callback: (Int, Element) -> ()) -> [Element]For each item in the array invoke the callback by passing the elem along with the index
let array = ["foo", "spam", "bar", "eggs"]
array.each { (index, elem)
print("\(index) - \(elem)")
}
=> ["foo", "spam", "bar", "eggs"]
cycle<U>(times: Int, callback: (Element) -> U)Cycles through the array definetly or indefinetly passing each element into the callback function. The second parameter is to specify how many times to cycle through the array. If left out it will cycle indefinetly.
[1, 2, 3].cycle(2) {
print($0)
}
// Prints the following
123123
[1, 2, 3].cycle {
print($0)
}
// Cycles in an infinite loop
every(callback: (Element) -> Bool) -> BoolChecks if the given callback returns true value for all items in the array.
["angry", "hungry"].every { (a: String) -> (Bool) in
a.hasSuffix("gry")
}
=> true
indexOf<T: Equatable>(value: T) -> IntGets the index at which the first occurrence of value is found.
let array = ["foo", "spam", "bar", "eggs"]
array.indexOf("spam")
=> 1
array.indexOf("None")
=> nil
fetch(index: Int, orElse: T? = .None) -> T!Get element from an array at the given index which can be negative to find elements from the end of the array. A default value can be returned if indexing out of bounds.
let arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr.fetch(100)
=> nil
arr.fetch(100, orElse: 42)
=> 42
arr.fetch(-1)
=> 8
findIndex(callback: (Element) -> Bool) -> Int?This method is like find except that it returns the index of the first element that passes the callback check.
let ind: int? = ["foo", "bar", "spam", "eggs"].findIndex {
$0.length == 4
}
ind! == 2
=> true
findLastIndex(callback: (Element) -> Bool) -> Int?This method is like findIndex except that it iterates over elements of the array from right to left.
let ind: int? = ["foo", "bar", "spam", "eggs"].findLastIndex {
$0.length == 4
}
ind! == 3
=> true
first() -> Element?Gets the first element in the array.
let first = ["foo", "bar"].first()
=> "foo"
flatten() -> [Element]Flattens a nested array of any depth.
let unFlattened = ["foo", ["bar"], [["spam"]], [[["eggs"]]] ]
let flattened = unFlattened.flatten()
=> ["foo", "bar", "spam", "eggs"]
get(index: Int) -> Element?Get element at index
let element = ["foo", "bar"].get(0)
element!
=> "foo"
let nothing = ["foo", "bar"].get(1000)
=> nil
initial(numElements: Int? = 1) -> [Element]Gets all but the last element or last n elements of an array.
let initial = ["foo", "bar", "spam"].initial(2)
=> ["foo"]
last() -> Element?Gets the last element from the array.
let last = ["foo", "bar"].last()
=> "bar"
rest(numElements: Int? = 1) -> [Element]The opposite of initial this method gets all but the first element or first n elements of an array.
let rest = ["foo", "bar", "spam"].rest(2)
=> ["spam"]
min<T: Comparable>() -> T?Retrieves the minimum value in an array.
let min = [ 0, 1, 2 ].min()
=> 0
max<T: Comparable>() -> T?Retrieves the maximum value in an array.
let max = [ 0, 1, 2].max()
=> 2
remove<T: Equatable>(value: T) -> T?Remove element from array
var arr = ["A", "B", "C", "D", "E"]
arr.remove("B")
=> ["A", "C", "D", "E"]
contains<T:Equatable>(value: T) -> BoolChecks if a given value is present in the array.
var arr = ["A", "B", "C", "D", "E"]
arr.contains("C")
=> true
arr.contains("Z")
=> false
"A".description -> StringGet string description of Character
let ch: Character = "A"
let str = ch.description
=> "A"
"A".ord -> IntGet int representation of character
Character("A").ord
=> 65
Date.from(#year: Int, month: Int, day: Int) -> NSDateReturns a new Date given the year month and day
let date = Date.from(2014, 1, 1)
=> "Jan 1, 2014, 12:00 AM"
Date.from(#unix: Double) -> NSDateReturns a new Date given the unix timestamp (timeIntervalSince1970)
let date = Date.from(unix: 1_388_552_400.0)
=> "Jan 1, 2014, 12:00 AM"
Date.parse(dateStr: String, format: String = "yyyy-MM-dd") -> NSDateParses the date based on the format and return a new Date
let parsedDate = Date.parse("2014-01-01", format: "yyyy-MM-dd")
=> "Jan 1, 2014, 12:00 AM"
Date.unix(date: NSDate = NSDate()) -> DoubleReturns the unix timestamp of the date passed in or the current unix timestamp
let currentUnix = Date.unix()
=> 1,388,552,400.0
var otherNSDate = Date()
let otherUnix = Date.unix(otherDate)
=> 1,388,552,400.0
Int.hour.fromNow et al.Use the following syntax to calculate dates and times based on the user's current calendar.
1.day.ago
=> "Apr 10, 2015, 11:51 AM"
4.hours.fromNow
=> "Apr 11, 2015, 3:51 PM"
merge<K, V>(dictionaries: Dictionary<K, V>...)Merges the dictionary with dictionaries passed. The latter dictionaries will override values of the keys that are already set
var dic = ["foo": "bar"]
let anotherDic = ["foo": "baz", "spam": "eggs"]
dic.merge(anotherDic)
=> ["foo": "baz", "spam": "eggs"]
times(callback: (Int) -> ())Invoke a callback n times with callback that takes index
5.times { print("Na") }
=> "NaNaNaNaNa"
times (function: () -> ())Invoke a callback n times
5.times { (a: Int) -> () in print("\(a) ") }
=> 0 1 2 3 4
char -> CharacterGet ASCII character from integer
65.char
=> "A"
isEvenCheck if int is even
2.isEven
=> true
1.isEven
=> false
isOddCheck if int is odd
3.isOdd
=> true
2.isOdd
=> false
digits() -> [Int]Splits the int into array of digits
4208.digits()
=> [4, 2, 0, 8]
lcm() -> IntLCM method return least common multiple with number passed
3.lcm(10)
=> 30
3.lcm(9)
=> 9
gcd() -> IntGCD method return greatest common denominator with number passed
3.gcd(10)
=> 1
3.gcd(9)
=> 3
random() -> IntReturns random number from 0 upto but not including value of integer
3.random()
=> 2
3.random()
=> 1
factorial() -> IntReturns factorial of integer
3.factorial()
=> 6
0.factorial()
=> 1
isIn(interval) -> BoolReturns true if i is in interval or range
5.isIn(1...10)
=> true
10.isIn(1..<10)
=> false
next() -> IntGet the next int
10.next()
=> 11
prev() -> IntGet the previous int
10.prev()
=> 9
upTo(limit: Int, callback: () -> ())Invoke the callback from int up to and including limit
3.upTo(5) {
print("Hi")
}
Prints "HiHiHi"
downTo(limit: Int, callback: () -> ())Invoke the callback from int down to and including limit
3.downTo(0) {
print("Hi")
}
Prints "HiHiHiHi"
.lengthGet the length of the string
"Hello".length
=> 5
.camelCaseGet the camel case representation of the string
"__Dollar and cent-- dollarANDCent".camelCase
=> "dollarAndCentDollarAndCent"
.kebabCaseGet the kebab case representation of the string
"__Dollar and cent-- dollarANDCent".kebabCase
=> "dollar-and-cent-dollar-and-cent"
.snakeCaseGet the snake case representation of the string
"__Dollar and cent-- dollarANDCent".snakeCase
=> "dollar_and_cent_dollar_and_cent"
.startCaseGet the start case representation of the string
"__Dollar and cent-- dollarANDCent".startCase
=> "Dollar And Cent Dollar And Cent"
=~ str: String -> BoolDoes a regex match of whether regex string on the right is matches the string on the left
"Dollar" =~ "oll"
=> true
* n: Int -> StringGet string concatenated n times
"Hi Swift! " * 3
=> "Hi Swift! Hi Swift! Hi Swift! "
[i: Int] -> Character?Get character at a subscript
"Hello World"[6] == "W"
=> true
"Hi"[5]
=> nil
[str: String] -> String?Returns the substring based on the first regex match passed in the subscript
let proj = "Dollar and Cent"
proj["^.+[^and Cent]"]
=> {Some: "Dollar"}
[r: Range<Int>] -> StringGet substring using subscript notation and by passing a range
"Hello World"[0..<5] == "Hello"
=> true
indexOf(char: Character) -> Int?Get the start index of character
"hello world".indexOf(Character("o"))!
=> 4
indexOf(str: String) -> Int?Get the start index of string
"hello world".indexOf("llo")!
=> 2
"hello world".indexOf("illo")
=> nil
indexOf(pattern: String) -> Int?Get the start index of regex pattern inside the string
"hello world".indexOf(".llo")!
=> 1
split(delimiter: Character) -> [String]Get an array from string split using the delimiter character
"Hello World".split(" ")
=> ["Hello", "World"]
lstrip() -> StringGet string without leading spaces
let leadingSpace = " Hello"
leadingSpace.lstrip()
=> "Hello"
rstrip() -> StringGet string without trailing spaces
let trailingSpace = "Hello "
trailingSpace.rstrip()
=> "Hello"
strip() -> StringGet string without leading or trailing spaces
let spaces = " Hello "
spaces.strip()
=> "Hello"
initInit with regex pattern as string
Regex.init("^Hello.World$") // Regex that matches "Hello World"
matches(testStr: String) -> [AnyObject]Return matches based on String passed.
let re = Regex.init("^Hello.World$")
re.matches("Hello World")
test(testStr: String) -> Boollet re = Regex.init("^Hello.World$")
re.test("Hello World")
=> true
re.test("Str")
=> false
escapeStr(str: String) -> StringEscape string with regex characters
Regex.escape("Hello.World")
=> "Hello\.World"
==Check the equality of two ranges
(1...5) == (1...5)
=> true
(1..<5) == (1...5)
=> false
eachWithIndex(callback: (T) -> ())For each index in the range invoke the callback by passing the item in range
(1...5).eachWithIndex { (a: Int) -> () in print("\(a)") }
=> 12345
each(callback: () -> ())For each index in the range invoke the callback
(1...5).each { print("Na") }
=> "NaNaNaNaNa"
If you are interested in contributing checkout CONTRIBUTING.md
6,173 followers · starred Jun 2014
156 followers · starred Nov 2015
1,590 followers · starred Aug 2021
188 followers · starred Oct 2014