Underscore.m
a functional toolbelt for Objective-C
Underscore.m is a small utility library to facilitate working with common data structures in Objective-C.
It tries to encourage chaining by eschewing the square bracket]]]]]].
It is inspired by the awesome underscore.js. Underscore.m was written by Robert Böhnke and is MIT licensed.
Examples
Consider these Hello World! strings:
Underscore.m makes extracting the strings and capitalizing them a breeze.
Underscore.m is especially useful when you deal with structured data from web APIs.
Installation
It is recommended to use CocoaPods to install Underscore.m. Alternatively you can download the code from GitHub.
You may want to alias Underscore
to _
to make accessing Underscore.m’s
methods more concise.
NSArray
The following methods can be used with NSArray
and NSMutableArray
instances.
With Underscore.m’s array methods can use a functional-style syntax as well as
chaining to create powerful expressions.
Underscore.m supports the following methods to manipulate arrays:
array Underscore.array(NSArray *array)
Wraps an array in an USArrayWrapper
. Use this method if you want to chain
multiple operations together. You will need to call unwrap
to extract the
new array at the end.
Since array
is meant for chaining, you probably don’t need to keep a
reference to the USArrayWrapper
.
unwrap wrapper.unwrap
Extracts the array of an USArrayWrapper
.
first Underscore.first(NSArray *array)
Returns the first element of the array or nil
if it is empty.
last Underscore.last(NSArray *array)
Returns the last element of the array or nil
if it is empty.
head Underscore.head(NSArray *array, NSUInteger n)
Returns the first n
elements or all of them, if there are less than n
elements in the array.
tail Underscore.tail(NSArray *array, NSUInteger n)
Returns the last n
elements or all of them, if there are less than n
elements in the array.
indexOf Underscore.indexOf(NSArray *array, id obj)
Returns the index of the first occurrence of obj
in array
or NSNotFound
,
if the element could not be found.
flatten Underscore.flatten(NSArray *array)
Recursively flattens the array.
without Underscore.without(NSArray *array, NSArray *values)
Returns all elements not contained in values
.
shuffle Underscore.shuffle(NSArray *array)
Shuffles the array using the Fisher-Yates-Shuffle.
reduce Underscore.reduce(id memo, UnderscoreReduceBlock block)
reduceRight Underscore.reduceRight(id memo, UnderscoreReduceBlock block)
Reduces the array to a single value using the block
.
each wrapper.each(UnderscoreArrayIteratorBlock block)
arrayEach Underscore.arrayEach(NSArray *array, UnderscoreArrayIteratorBlock block)
Calls block
once with every member of the array.
This method returns the same array again, to facilitate chaining.
Functional syntax:
Chaining:
map wrapper.map(UnderscoreArrayMapBlock block)
arrayMap Underscore.arrayMap(NSArray *array, UnderscoreArrayMapBlock block)
Calls block
once with every element of the array. If the block returns nil
,
the object is removed from the array. Otherwise, the return-value replaces the
object.
Functional syntax:
Chaining:
pluck Underscore.pluck(NSArray *array, NSString *keyPath)
Returns an array containing the objects’ values for the given key path.
uniq Underscore.uniq(NSArray *array)
Returns a new array containing all elements of array
exactly once.
find Underscore.find(NSArray *array, UnderscoreTestBlock test)
Returns an object from the array the passes the test
or nil
, if none of the
elements match.
filter Underscore.filter(NSArray *array, UnderscoreTestBlock test)
Returns all elements that pass the test
.
reject Underscore.reject(NSArray *array, UnderscoreTestBlock test)
Returns all elements that fail the test
.
all Underscore.all(NSArray *array, UnderscoreTestBlock test)
Returns YES
if all elements pass the test
.
any Underscore.any(NSArray *array, UnderscoreTestBlock test)
Returns YES
if any of the elements pass the test
.
NSDictionary
The following methods can be used with NSDictionary
and NSMutableDictionary
instances. With Underscore.m’s dictionary methods can use a functional-style
syntax as well as chaining to create powerful expressions.
Underscore.m supports the following methods to manipulate dictionaries:
dict Underscore.dict(NSDictionary *dictionary)
Wraps a dictionary in an USDictionaryWrapper
. Use this method if you want to
chain multiple operations together. You will need to call unwrap
to extract
the result.
Since dict
is meant for chaining, you probably don’t need to keep a
reference to the USDictionaryWrapper
.
unwrap wrapper.unwrap
Extracts the dictionary of an USDictionaryWrapper
.
keys Underscore.keys(NSDictionary *dictionary)
Returns the keys of a dictionary.
When called on a USDictionaryWrapper
, it returns a USArrayWrapper
to
facilitate chaining.
values Underscore.values(NSDictionary *dictionary)
Returns the values of a dictionary.
When called on a USDictionaryWrapper
, it returns a USArrayWrapper
to
facilitate chaining.
each wrapper.each(UnderscoreDictionaryIteratorBlock block)
dictEach Underscore.each(NSDictionary *dictionary, UnderscoreDictionaryIteratorBlock block)
Calls block
once with every key-value pair of the dictionary.
This method returns the same dictionary again, to facilitate chaining.
Functional syntax:
Chaining:
map wrapper.map(UnderscoreDictionaryMapBlock block)
dictMap Underscore.map(NSDictionary *dictionary, UnderscoreDictionaryMapBlock block)
Calls block
once with every key-value pair of he dictionary.
If the block returns nil
, the key-value-pair is removed from the dictionary.
Otherwise, the return-value replaces the value.
Functional syntax:
Chaining:
pick Underscore.pick(NSDictionary *dictionary, NSArray *keys)
Returns a copy of dictionary
that contains only the keys contained in keys
.
extend Underscore.extend(NSDictionary *destination, NSDictionary *source)
Returns a dictionary that contains a union of key-value-pairs of destination
and source
. Key-value-pairs of source
will have precedence over those taken
from destination
.
defaults Underscore.defaults(NSDictionary *dictionary, NSDictionary *defaults)
Returns a dictionary that contains a union of key-value-pairs of dictionary
and defaults
. Key-value-pairs of destination
will have precedence over those
taken from defaults
.
A common use case for defaults
is sanitizing data with known values.
filterKeys Underscore.filterKeys(NSDictionary *dictionary, UnderscoreTestBlock test)
Returns a dictionary that only contains the key-value-pairs whose keys pass
test
.
filterValues Underscore.filterValues(NSDictionary *dictionary, UnderscoreTestBlock test)
Returns a dictionary that only contains the key-value-pairse whose values pass
test
.
rejectKeys Underscore.rejectKeys(NSDictionary *dictionary, UnderscoreTestBlock test)
Returns a dictionary that only contains the key-value-pairs whose keys fail
test
.
rejectValues Underscore.rejectValues(NSDictionary *dictionary, UnderscoreTestBlock test)
Returns a dictionary that only contains the key-value-pairs whose values fail
test
.
Helpers
negate Underscore.negate(UnderscoreTestBlock block)
Returns a block that negates block
isEqual Underscore.isEqual(id obj)
Returns a block that returns YES
whenever it is called with an object equal to obj.
isArray Underscore.isArray
A block that returns YES
if it is called with an NSArray.
isDictionary Underscore.isDictionary
A block that returns YES
if it is called with an NSDictionary.
isNull Underscore.isNull
A block that returns YES
if it is called with an NSNull.
isNumber Underscore.isNumber
A block that returns YES
if it is called with an NSNumber.
isString Underscore.isString
A block that returns YES
if it is called with an NSString.