Transforming an object to array in JavaScript
Tags: webdev, rambda, tips, devtips
Published: 2020-11-27 09:25:31

---
title: Transforming an object to array in JavaScript
published: true
date: 2020-11-09 00:00:00 UTC
tags: webdev,rambda,tips,devtips
canonical_url: https://codechips.me/object-to-array-with-js-and-rambda/
---

When working with objects in JavaScript sometimes it's convenient to transform them to arrays. In this short post I will show you how to do it in plain JavaScript and also with Rambda.js.

Let's say that we have a nested JavaScript object that looks like this. If you work with Firebase Firestore, or some of Google Cloud Platform's or AWS API, you might have stumbled on structures like these.

```js
const obj = {
  id: 'one',
  services: {
    'service-foo': {
      slug: 'foo',
      public: true,
      readonly: true,
    },
    'service-bar': {
      slug: 'bar',
      public: false,
      readonly: true,
      users: ['john', 'jane'],
    },
    'service-baz': {
      slug: 'baz',
      public: false,
      readonly: false,
      users: ['bo', 'bill', 'brooke'],
    },
  },
};

```

Say we want to display the `services` property as a list on the page. While it's possible to loop over the object itself, it's more convenient to loop over a list that looks like this.

```js
[
  {
    id: 'service-foo',
    slug: 'foo',
    public: true,
    readonly: true,
    users: [ 'frank', 'finn', 'fernando' ]
  },
  {
    id: 'service-bar',
    slug: 'bar',
    public: false,
    readonly: true,
    users: [ 'john', 'jane' ]
  },
  {
    id: 'service-baz',
    slug: 'baz',
    public: false,
    readonly: false,
    users: [ 'bo', 'bill', 'brooke' ]
  }
]
```

How can we transform our our `services` property object to an array?

## Transforming with plain JavaScript

One obvious way is to do it in plain JavaScript. Like this.

```js
const transform = obj => Object.keys(obj).map(id => ({ id, ...obj[id] }));

console.log(trasform(obj.services));
```
We map over object's keys and construct a new object consisting of the object's key and its properties with the help of the ES spread operator.

## Transforming object with Rambda.js

I was curious how to achieve the same results with [Rambda](https://ramdajs.com/) - a functional programming library for JavaScript.

Turns out there are two ways to do it.

First one is to use Ramda's [pipe](https://ramdajs.com/docs/#pipe) operator.

```js
const R = require('rambda');

const transform= R.pipe(
  R.toPairs,
  R.map(([id, props]) => ({ id, ...props }))
);

console.log(trasform(obj.services));
```

Second is to use Ramda's [compose](https://ramdajs.com/docs/#compose) operator.

```js
const R = require('rambda');

const transform = R.compose(
  R.map(([id, props]) => ({ id, ...props })),
  R.toPairs
);

console.log(trasform(obj.services));
```

Both results in the same output. It's only a matter of taste. If you are coming form an FP background, `compose` will look more natural to you.

Let's break down Rambda's [toPairs](https://ramdajs.com/docs/#toPairs) operator. Maybe a better name for it would be `toTuple`.

```js
console.log(R.toPairs(obj.services));

[
  [
    'service-foo',
    { slug: 'foo', public: true, readonly: true, users: [Array] }
  ],
  [
    'service-bar',
    { slug: 'bar', public: false, readonly: true, users: [Array] }
  ],
  [
    'service-baz',
    { slug: 'baz', public: false, readonly: false, users: [Array] }
  ]
]
```

The `toPairs` operator loops over object's keys and returns key and property a list with two items in it - `[key, prop]`.

In functional programming you often work with lists as they are easier to manipulate.

## Rambda - pipe vs compose

What the difference when it comes to the two composition operators in Rambda - `pipe` and `compose`? It's subtle. In my opinion it's a matter of taste.

The `pipe` operator feels most intuitive to developers. It works like a pipe in Unix (`ls -l | grep js`), passing the results from one function to another in the chain from left to right. First function can take multiple arguments, but the rest of the functions in the chain can only have one argument as input. It reminds me a lot about the proposed [pipeline](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator) operator in JavaScript.

The `compose` operator does the opposite of pipe. It performs its operations right to left.

I find it intuitive to think of it as the Russian Doll pattern - `f4(f3(f2(f1([1,2,3]))))`, where each function is called inside out.

There are probably a few more ways to transform an object to array. Let me know then so I can learn something new.