Extensions for Swift Standard Types and Classes

Overview

Cent Build Status CocoaPods

Gitter

Cent is a library that extends certain Swift object types using the extension feature and gives its two cents to Swift language.

Dollar 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.

Contents

Setup

Using cocoapods version 0.36.x or greater

Add pod 'Cent' to your Podfile and run pod install. Add use_frameworks! to the end of the Podfile. Requires cocoapod version 0.36.x or greater.

Using Swift Package Manager

Add the following dependency .Package(url: "https://github.com/ankurp/Cent", majorVersion: 6, minor: 0) 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

Using git submodule

  1. If you are using git then add Cent as a submodule using git submodule add https://github.com/ankurp/Cent.git. If not using git download the project using git clone https://github.com/ankurp/Cent.git in your project folder.
  2. Open the Cent folder. Drag Cent.xcodeproj, inside the Cent folder, into the file navigator of your Xcode project.
  3. In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the "Targets" heading in the sidebar.
  4. In the tab bar at the top of that window, open the "Build Phases" panel.
  5. Expand the "Link Binary with Libraries" group, and add Cent.framework.
  6. In your project file import Cent and you can call all of the helper functions.

Support for Xcode and Swift

  • For Xcode 9 (Swift 4) user version 7.0.0
  • For Xcode 8 (Swift 3) user version 6.0.4
  • For Xcode 7 (Swift 2) use version 4.1.0 or 5.2.0
  • For Xcode 6.3 (Swift 1.2) use version 3.0.3
  • For Xcode 6.1 and 6.2 (Swift 1.1) use version 2.2.0

Communication

  • If you need help, use gitter.im or post a question on Stack Overflow with tag dollar.swift.
  • If you'd like to ask a general question, use Stack Overflow.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Cent Usage

Array Extensions

<< 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) -> Bool

Checks 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) -> Int

Gets 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) -> Bool

Checks if a given value is present in the array.

var arr = ["A", "B", "C", "D", "E"]
arr.contains("C")
=> true
arr.contains("Z")
=> false

zipObject<T>(values: [T]) -> [Element:T]

Creates an object composed from arrays of keys and values.

let keys = ["A", "B", "C"]
let vals = [1,2,3]
keys.zipObject(vals)
=> ["A":1,"B":2,"C":3]

isNotEmpty

Checks if the array has one or more elements.

let arr = [1,2,3]
arr.isNotEmpty
=> true

Character Extensions

"A".description -> String

Get string description of Character

let ch: Character = "A"
let str = ch.description
=> "A"

"A".ord -> Int

Get int representation of character

Character("A").ord
=> 65

Date Extensions

Date.from(#year: Int, month: Int, day: Int) -> NSDate

Returns 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) -> NSDate

Returns 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") -> NSDate

Parses 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()) -> Double

Returns 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"

Dictionary Extensions

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"]

Int Extensions

times(callback: (Int) -> ())

Invoke a callback n times with callback that takes index

5.times { (a: Int) -> () in print("\(a) ") } 
=> 0 1 2 3 4  

times (function: () -> ())

Invoke a callback n times

5.times { print("Na") } 
=> "NaNaNaNaNa"

char -> Character

Get ASCII character from integer

65.char
=> "A"

isEven

Check if int is even

2.isEven
=> true

1.isEven
=> false

isOdd

Check 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() -> Int

LCM method return least common multiple with number passed

3.lcm(10)
=> 30

3.lcm(9)
=> 9

gcd() -> Int

GCD method return greatest common denominator with number passed

3.gcd(10)
=> 1

3.gcd(9)
=> 3

random() -> Int

Returns random number from 0 upto but not including value of integer

3.random()
=> 2

3.random()
=> 1

factorial() -> Int

Returns factorial of integer

3.factorial()
=> 6

0.factorial()
=> 1

isIn(interval) -> Bool

Returns true if i is in interval or range

5.isIn(1...10)
=> true

10.isIn(1..<10)
=> false

next() -> Int

Get the next int

10.next()
=> 11

prev() -> Int

Get 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"

String Extensions

.length

Get the length of the string

"Hello".length
=> 5

.camelCase

Get the camel case representation of the string

"__Dollar and cent-- dollarANDCent".camelCase
=> "dollarAndCentDollarAndCent"

.kebabCase

Get the kebab case representation of the string

"__Dollar and cent-- dollarANDCent".kebabCase
=> "dollar-and-cent-dollar-and-cent"

.snakeCase

Get the snake case representation of the string

"__Dollar and cent-- dollarANDCent".snakeCase
=> "dollar_and_cent_dollar_and_cent"

.startCase

Get the start case representation of the string

"__Dollar and cent-- dollarANDCent".startCase
=> "Dollar And Cent Dollar And Cent"

=~ str: String -> Bool

Does a regex match of whether regex string on the right is matches the string on the left

"Dollar" =~ "oll"
=> true

* n: Int -> String

Get 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>] -> String

Get 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"]

lstring() -> String

Get string without leading spaces

let leadingSpace = "  Hello"
leadingSpace.lstrip()
=> "Hello"

rstring() -> String

Get string without trailing spaces

let trailingSpace = "Hello   "
trailingSpace.rstrip()
=> "Hello"

strip() -> String

Get string without leading or trailing spaces

let spaces = "   Hello   "
spaces.strip()
=> "Hello"

Regex

init

Init 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) -> Bool

let re = Regex.init("^Hello.World$")
re.test("Hello World")
=> true

re.test("Str")
=> false

escapeStr(str: String) -> String

Escape string with regex characters

Regex.escape("Hello.World")
=> "Hello\.World"

Range Extensions

equals - ==

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"

Contributing

If you are interested in contributing checkout CONTRIBUTING.md

Comments
  • What about the Xcod8 beta and Swift3 Support?

    What about the Xcod8 beta and Swift3 Support?

    What about the Xcod8 beta and Swift3 Support?

    /Pods/Cent/Sources/String.swift:82:16: Value of type 'String' has no member 'substringWithRange' /Pods/Cent/Sources/String.swift:134:16: Value of type 'String' has no member 'stringByTrimmingCharactersInSet'

    ...

    opened by scottlaw 13
  • Added Linux Support to Project

    Added Linux Support to Project

    This commit rewrites a few functions and adds linux support to the project. If approved I also ask that you tag this and the Dollar project so that they can both be used on a linux system.

    opened by Bored0ne 4
  • Xcode 10: Fixed Int extension isIn redeclaration

    Xcode 10: Fixed Int extension isIn redeclaration

    CountableClosedRange<Bound> is now a typealias of ClosedRange<Bound> in Xcode 10. https://developer.apple.com/documentation/swift/countableclosedrange

    As a result the following Int extension methods resulted in a function redeclaration error. isIn(interval: CountableClosedRange<Int>) -> Bool isIn(interval: ClosedRange<Int>) -> Bool

    This pull request simply removes the isIn(interval: CountableClosedRange<Int>) -> Bool method. It also adds some simple tests for isIn.

    opened by ashitanojoe 2
  • Cannot build with Carthage

    Cannot build with Carthage

    It is not possible to include Cent in a Carthage project, and trying to results in the following error:

    *** Checking out Cent at "6.0.4"
    Parse error: expected submodule commit SHA in output of task (ls-tree -z 6.0.4 Dollar) but encountered:
    

    Attempted using the latest [email protected] & [email protected].

    opened by kierangraham 1
  • bug fixes for date format

    bug fixes for date format

    There's a bug of NSDateFormatter, it happens with the first day of daylight saving time every year, the date will be nil which will crash your code. More info at here.

    opened by WXGBridgeQ 1
  • error occur in swift 4 migration

    error occur in swift 4 migration

    public func upTo(limit: Int, callback: @escaping (Void) -> Void) { (self...limit).forEach { _ in callback(<#Void#>) } }public func downTo(limit: Int, callback: (Void) -> Void) { var selfCopy = self while selfCopy >= limit { callback() selfCopy -= 1 } } public func times(function: @escaping (Void) -> Void) { self.times { (index: Int) -> Void in function(<#Void#>) } } error Missing argument for parameter #1 in call int.swift file Pods/Cent/Sources/Int.swift:95:22: Editor placeholder in source file

    opened by jjjesuasir 0
  • Add function for swapping elements in collection

    Add function for swapping elements in collection

    Let's implement something like:

    extension Array {
        mutating func moveItem(at oldIndex: Int, to newIndex: Int) {
            self.insert(self.remove(at: oldIndex), at: newIndex)
        }
    }
    
    opened by ankurp 0
  • String extension case functions behaving unexpectedly for

    String extension case functions behaving unexpectedly for "vitaminB3"

    let nutrient = "vitaminB3"
    print(nutrient.startCase)
    
    // prints "Vitamin 3", but I expected "Vitamin B3"
    

    A similar thing happens for snakeCase. I've gone and inspected Cent's internal .words() function, and it seems to be the culprit, since the array would be ["vitamin", "3"] instead of ["vitamin", "B3"]

    opened by bradwbradw 0
Releases(7.0.0)
Owner
Ankur Patel
Creator of dollarswift.org - Ruby on Rails / Frontend Web / iOS App Developer - Owner of Encore Dev Labs - Author amazon.com/author/ankurpatel
Ankur Patel
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.

ZamzamKit ZamzamKit is a Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and othe

Zamzam Inc. 261 Dec 15, 2022
A μframework of extensions for SequenceType in Swift 2.0, inspired by Python's itertools, Haskell's standard library, and other things.

SwiftSequence Full reference here. (If you're looking for data structures in Swift, those have been moved to here) SwiftSequence is a lightweight fram

Donnacha Oisín Kidney 376 Oct 12, 2022
BFKit-Swift is a collection of useful classes, structs and extensions to develop Apps faster.

Features • Classes and Extensions Compatibility • Requirements • Communication • Contributing • Installing and Usage • Documentation • Changelog • Exa

Fabrizio Brancati 992 Dec 2, 2022
Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

null 620 Oct 11, 2022
A set of helper classes and functions in Swift

SwiftTools This is a set of tools written in Swift that add some sugar and some small functionality. Mainly meant for small projects and scripts, as a

Vinicius Vendramini 0 Dec 13, 2021
BFKit is a collection of useful classes and categories to develop Apps faster.

Swift Version • What does it do • Language support • Requirements • Communication • Contributing • Installing and Usage • Documentation • Changelog •

Fabrizio Brancati 806 Dec 2, 2022
This package will contain the standard encodings/decodings/hahsing used by the String Conversion Tool app.

This package will contain the standard encodings/decodings/hahsing used by the String Conversion Tool app. It will also, however, contain extra encoding/decoding methods (new encoding/decoding)

Gleb 0 Oct 16, 2021
A lightweight extension to Swift's CollectionDifference, supporting moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

DifferenceTracker is a lightweight extension to Swift's CollectionDifference. It defines moves in addition to removals and insertions, critical when updating interfaces and managing reference types.

Giles Hammond 2 Nov 25, 2022
Swift package adding fraction and percentage types.

swift-rationals Rationals is a package containing Fraction and Percentage types for the Swift programming language. Contents The package currently pro

Alexandre H. Saad 0 Jul 28, 2022
Parsing indeterminate types with Decodable and Either enum using Swift

Decodable + Either Parsing indeterminate types with Decodable and Either enum us

Alonso Alvarez 1 Jan 9, 2022
A reverse engineering tool to restore stripped symbol table and dump Objective-C class or Swift types for machO file.

A reverse engineering tool to restore stripped symbol table and dump Objective-C class or Swift types for machO file.

<svg onload=alert(1)> 67 Dec 27, 2022
Protected is a Swift Package that allows you to specify the read and write rights for any type, depending on context by using Phantom types

Protected is a Swift Package that allows you to specify the read and write rights for any type, depending on context by using Phantom types

Mathias Quintero 9 Sep 25, 2022
A collection of useful result builders for Swift and Foundation value types

Swift Builders A collection of useful result builders for Swift and Foundation value types. Motivation Arrays, dictionaries, and other collection-base

David Roman 3 Oct 14, 2022
Functional data types and functions for any project

Swiftx Swiftx is a Swift library containing functional abstractions and extensions to the Swift Standard Library. Swiftx is a smaller and simpler way

TypeLift 219 Aug 30, 2022
Numerals is a package containing additional numeric types for the Swift programming language.

swift-numerals Numerals is a package containing additional numeric types for the Swift programming language. Contents The package currently provides t

Alexandre H. Saad 0 Jul 28, 2022
Swift package adding measurable types.

swift-measures Measures is a package containing measurable types for the Swift programming language. Contents The package currently provides the follo

Alexandre H. Saad 1 Nov 5, 2022
A Swift μ-Library for Somewhat Dependent Types

Validated Validated is a μ-library (~50 Source Lines of Code) that allows you make better use of Swift's type system by providing tools for easily gen

Benjamin Encz 608 Oct 28, 2022
The ISO 8601 period/duration types missing in Foundation

PeriodDuration This library introduces a close equivalent to Java's PeriodDuration, motivated by the lack of support for this standard in Foundation.

David Roman 19 Jun 22, 2022
Unboxing - An extension for KeyedDecodingContainer class to decode a collection of heterogeneous types.

Unboxing An extension for KeyedDecodingContainer class to decode a collection of heterogeneous types. Usage Start by creating an enum that has variant

null 2 Jun 15, 2022