Refactoring chronicles: Extract unique values from an array of objects
Tags: refactoring, codereviews, es6, javascript
Published: 2019-03-18 09:26:19

---
title: Refactoring chronicles: Extract unique values from an array of objects
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ysaf0iks6evfnm7hg9re.png
description: Suggestions, tips and some thoughts straight out code reviews and pair programming.
tags: #refactoring, #codereviews, #es6, #javascript
---
Quick note out of a code review I made today.
Use-case was extracting the list of all unique IDs out of all the rows of a CSV file.

After loading the CSV and parsing, the array looked like this:
```
const rows = [
  {"id":1,"date":"03.03.2019","otherProps":483},
  {"id":2,"date":"22.02.2019","otherProps":573},
  {"id":3,"date":"11.03.2019","otherProps":645},
  {"id":4,"date":"03.03.2019","otherProps":483},
  {"id":2,"date":"08.03.2019","otherProps":573},
  {"id":4,"date":"26.02.2019","otherProps":645},
  {"id":5,"date":"13.03.2019","otherProps":483},
  {"id":3,"date":"22.01.2019","otherProps":573},
  {"id":1,"date":"01.03.2019","otherProps":645}
];
```
implementation in the Pull Request was this:
```
const findUnique = (arr) => {
  return arr.reduce((acc, row) => {
            if (typeof row.id === 'number' && acc.indexOf(row.id) < 0) {
                acc.push(row.id)
            }
            return acc
        }, [])
}
```
I really appreciated that the dev tried to use _reduce_ here but as useful and cool  reduce is, I found the code too verbose.

IMHO a more readable solution might have been first estracting only the IDs to remove the clutter and then filter for the first occurence of each and ignore the duplicates.

```
const findUnique = (arr) => arr.map(r => r.id).filter((id, i, ar) => ar.indexOf(id) == i)
```
but my suggestion was this  magical es6 trick that would make that function a one-liner

```
const findUnique = (arr) => [ ...new Set(arr.map(r => r.id))]
```
What is this doing?
We are extracting via _map_ the IDs and creating a Set with the result. 
Since as stated in the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Description) **A value in the Set may only occur once; it is unique in the Set's collection.** all duplicates are automagically removed. 
Then using the **... operator** we convert the Set back into an Array. 

![tadaa](https://media.giphy.com/media/8FfwJr9MnLw7OZBCrw/giphy.gif)

PS: Always be cautious when using _map reduce filter_ and other magick tricks ( like here the conversion of an Array into a Set and back) because with *very* big arrays performance might be affected. In such case, it is best to sacrifice readability and coolness and execute all the necessary operation in a single loop so that array is traversed only once.

PPS: Always have Unit Tests for your methods so that when trying out other solutions you are sure your code still works as intended.

```
import test from "ava"
test('return list of unique IDs', t => {
    const expected = [1, 2, 3, 4, 5]
    const result = findUnique(rows);
    t.deepEqual(result, expected)
}
```

You can play around with the code and try out other solutions with this [CodePen](https://codepen.io/anon/pen/moXYZe?editors=0012)