RockOn pt 6: 5 Useful Lodash functions
Tags: javascript, react
Published: 2020-07-30 20:53:54

*This is the sixth and final post in my series about building [RockOn](https://rockonapp.com). Get the full background starting [here](https://dev.to/dianakw8591/rockon-pt-1-using-nokogiri-to-seed-my-database-2h05).*

In last weeks [post](https://dev.to/dianakw8591/rockon-pt-5-filtering-data-3moo), I left off with an array of filtered "entry" objects. The final step is presenting stats and graphs of that data, but there's still more manipulation needed. That's where [Lodash](https://lodash.com/) comes in - a Javascript library that provides a ton of useful methods for working with arrays, objects, and other data types. The collection methods can be used for both arrays and objects which is incredibly useful. Lodash has excellent documentation, but I'll share a handful of methods I found particularly useful and how to implement them.

To review, here is an example of an entry object and the different keys I used to group and sort by:
```
{
 climb: {
  area_array: ["International", "Europe", "Spain", 
   "Catalonia", "…],
  climb_id: 110372,
  full_type: "Sport",
  key_type: "Sport",
  name: "La Discórdia",
  numeric_rating: 13,
  rating: "5.10"
 }
 beta: "",
 notes: "very cold and raining...",
 outcome: "Onsight",
 partners: "",
 pitches: 1,
 rack: "",
 start_date: "2019-11-23",
 style: "Lead",
}
```
My initial data was an array of these objects - when I use `array` in the examples below, that is the array I'm referencing. 

### Getting Started with Lodash

Install Lodash in your React app with `yarn` or `npm`, and then import specific functions into a component like so:
```react
import { startCase } from 'lodash';
```
or the whole library: 
```react
import _ from 'lodash';
```
When the whole library is imported, functions all begin with `_.` (`startCase` becomes `_.startCase`) but with cherry-picked functions you can simply call `startCase`.

### Useful Lodash Methods

**_.groupBy**
Takes a collection and method by which to group elements of that collection, returning an object where the keys are the result of applying that method to each element, and values are arrays of the elements that produced each key. In my case, I often wanted to group by different keys in my entry object, `start_date` for example:
```react
const groupByDate = _.groupBy(array, 'start_date')
```
`groupedByDate` is an object where the keys are every unique start date, and the values are arrays of entries that have that start date. With this function I could easily group climbs that happened on the same day! Let's say I wanted to see all the climbs from yesterday - `2020-07-29`. I could simply call `groupByDate['2020-07-29']` and get an array of all climbs from yesterday!

By linking `_.groupBy` methods together, I was able to easily collect all entries of a particular type, grade, and style which I used specifically to build my bar chart.

**_.maxBy**
Takes a collection and a method (iteratee) invoked on each element, and returns the element that generates the maximum value when the iteratee is called. I used this method to select the hardest climb by grade on each day.
```react
 _.maxBy(value, 'climb.numeric_rating')
```
where `value` is the array of climbs on a given day - for example, `groupByDate['2020-07-29']`. To create an array of entries that were the hardest climb done each day I combined this with...

**_.map**
Similar to Javascript's built in `map`, but can be applied to an object as well as an array. With an object, the values are the first argument passed to the iterator function - index/key and collection can also be passed. Returns an array.
```react
const maxByDate = _.map(groupByDate, (value) => _.maxBy(value, 'climb.numeric_rating')
```

**_.sortBy**
Similar to `groupBy`, `sortBy` takes a collection and the method by which to sort the elements in ascending order, returning a sorted array. Using this method I easily sorted my `maxByDate` array into ascending order:
```react
_.sortBy(maxByDate, 'start_date');
```
This ordered array is now ready to be plotted on a time vs difficulty plot!

**_.invert**
This function flips an Object's keys and values. In my case, I used it to transform my maps for converting Yosemite Decimal System climbing grades to numeric grades that were easier to implement in my graphs. 
```react
const yds_conversion = {
 ...
    "5.7": 8,
    "5.8": 9,
    "5.9": 10,
    "5.10": 13,
    "5.10-": 11,
    "5.10+": 14,
    "5.10a": 11,
    "5.10b": 12,
    "5.10c": 13,
    "5.10d": 14,
...
```
But I often had to map both ways, and `invert` allowed me to easily build the reverse mapping hash. Note that when keys are repeated, later values override earlier values. So when `yds_conversion` is inverted, the key `14` will have the value `"5.10d"`. 

### That's just the beginning...

Lodash has a rich library of functions that go way beyond Javascript's built in libraries. Again, their documentation is great, so don't be afraid to dive in and try some out!

That brings us to the end of my series about [RockOn](https://rockonapp.com). Hopefully there have been some useful bits along the way, and thanks for reading!