JavaScript arrays (as of ES5) have a core set of iteration methods (i.e., methods that apply functions to elements in the array).
While underscore and lodash provide a raft of supplemental collection utilities, there are times when ...
- you're working server side, so ancient browser compatability is not a concern
- you only need a few extra methods
- you'd like to use them as if they were native array methods.
For example, groupBy, countBy, and indexBy are extremely convenient tools for many data summarization tasks.
What if you want to use them just as you would map
, filter
, and reduce
?
See array-ext.coffee.md
for a demonstration of how Array
can be supplemented with the three aforementioned summarization methods and below for usage examples.
Note that we're just adding methods to Array.prototype. This can cause issues with javascript's native for..in
(enumeration-based) looping, but doesn't affect coffeescript's analogous constructs due to how these get compiled down.
Groups a list's values by a criterion. Pass a function that returns the criterion.
isLessThan = (x) -> # grouping function
(y) -> y < x
expected =
true: [1, 2, 3, 4]
false: [5, 6, 7, 8]
eq [1..8].groupBy(isLessThan(5)), expected
data = ['x', 'xx', 'y', 'yy', 'zzz']
length = (x) -> x.length # grouping function
expected =
1: ['x', 'y']
2: ['xx', 'yy']
3: ['zzz']
eq data.groupBy(length), expected
Counts instances of a list that group by a certain criterion. Pass a a function that returns the criterion to count by. Similar to groupBy
, but instead of returning a list of values, returns a count for the number of values in that group.
parity = (x) -> if x % 2 == 0 then 'even' else 'odd' # grouping function
expected =
odd: 3
even: 2
eq [1..5].countBy(parity), expected
Indexes the object’s values by a criterion. Similar to groupBy
, but for when you know that your index values will be unique.
people = [
{ id: 100, name: 'Bob' }
{ id: 101, name: 'Ann' }
{ id: 102, name: 'Rex' }
]
expected = {
'100': { id: 100, name: 'Bob' }
'101': { id: 101, name: 'Ann' }
'102': { id: 102, name: 'Rex' }
}
eq people.indexBy((p) -> p.id), expected
Underscore has some nice sub-libraries for working with arrays.
If you want functions to build arrays, see array.builders.
If you want functions to take things from arrays, see array.selectors
If you want to do multi-level nesting on array elements (i.e., groupBy
with hierarchical grouping criteria) see nest.