A step-by-step guide on transforming an array of objects into an array of arrays with the help of Ramda

I want to convert the following data:

[
  { a: 2000, b: 4000 },
  { a: 8000, b: 5000 },
  { a: 6000, b: 1000 }
];

Into this format:

[
  [ 2000, 8000, 6000 ],
  [ 4000, 5000, 1000 ]
];

Using Ramda library.

I am able to achieve this using R.reduce function, but I am exploring if there is a more efficient way using built-in functions provided by Ramda.

One important point; the solution should not assume fixed keys in the objects. The keys will remain consistent across objects but may vary each time the function runs. For instance, consider the following input:

Input:

[
  { c: 1000, d: 4000, e: 7000 },
  { c: 2000, d: 5000, e: 8000 },
  { c: 3000, d: 6000, e: 9000 }
];

Result:

[
  [ 1000, 2000, 3000 ],
  [ 4000, 5000, 6000 ],
  [ 7000, 8000, 9000 ],
];

Answer №1

Utilize vanilla JavaScript to transpose the values of the mapped object.

transpose(input.map(Object.values));

const transpose = (a) => a[0].map((_, i) => a.map(r => r[i]));

{
  const
    input = [
      { a: 2000, b: 4000 },
      { a: 8000, b: 5000 },
      { a: 6000, b: 1000 }
    ],
    expected = [
      [ 2000, 8000, 6000 ],
      [ 4000, 5000, 1000 ]
    ],
    actual = transpose(input.map(Object.values));

  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}

{
  const
    input = [
      { c: 1000, d: 4000 },
      { c: 2000, d: 5000 },
      { c: 3000, d: 6000 }
    ],
    expected = [
      [ 1000, 2000, 3000 ],
      [ 4000, 5000, 6000 ]
    ],
    actual = transpose(input.map(Object.values));

  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}

The Rambda equivalent code:

R.transpose(R.map(R.values, input));             // or
R.transpose(R.compose(R.map(R.values))(input));

{
  const
    input = [
      { a: 2000, b: 4000 },
      { a: 8000, b: 5000 },
      { a: 6000, b: 1000 }
    ],
    expected = [
      [ 2000, 8000, 6000 ],
      [ 4000, 5000, 1000 ]
    ],
    actual = R.transpose(R.map(R.values, input));

  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}

{
  const
    input = [
      { c: 1000, d: 4000 },
      { c: 2000, d: 5000 },
      { c: 3000, d: 6000 }
    ],
    expected = [
      [ 1000, 2000, 3000 ],
      [ 4000, 5000, 6000 ]
    ],
    actual = R.transpose(R.map(R.values, input));

  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.min.js"></script>

Answer №2

If the order of properties in your input objects remains constant, this solution is rather elegant:

const group = compose(transpose, map(values))

console.log(group([{a: 2000, b: 4000}, {a: 8000, b: 5000},{a: 6000, b: 1000}]))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.js"></script>
<script>const {compose, transpose, map, values} = R                  </script>

However, if the property order cannot be guaranteed, a bit more effort will be required. Although this point-free version functions properly:

const group = compose(transpose, chain(compose(map, props), compose(keys, head)))

console.log(group([{a: 2000, b: 4000}, {a: 8000, b: 5000},{a: 6000, b: 1000}]))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.js"></script>
<script>const {transpose, chain, compose, map, props, keys, head} = R</script>

I personally find it less clear compared to the named function approach:

const group = (input) => 
  transpose(map(props(keys(head(input))))(input))

console.log(group([{a: 2000, b: 4000}, {a: 8000, b: 5000},{a: 6000, b: 1000}]))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.js"></script>
<script>const {transpose, chain, map, props, keys, head} = R         </script>

Additionally, as mentioned by Mr. Polywhirl, creating a basic custom transpose function allows for achieving a similar outcome easily with vanilla JS.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Converting Venn diagram code from JavaScript <script> tags to Angular 2: A step-by-step guide

I am struggling to incorporate a Venn diagram into my Angular 2+ project. I followed the code sample provided at - http://jsfiddle.net/johnpham92/h04sknus/ To begin, I executed the following command - npm install venn.js Then I proceeded with impl ...

When the page is resized for mobile, the Bootstrap modal shifts downwards

I am encountering an issue with a modal that pops up on my webpage when clicked. It is perfectly centered in a browser view and smaller views. However, when I resize the page for phones, the modal shifts down the page and requires scrolling to see it. How ...

Showing the number of guilds as an action displayed on the screen

I'm trying to make my bot say "Watching (number of servers it's in) servers!" with this code: const activities_list = [ "with the &help command.", "with the developers console", "with some code", "with JavaScript", client.guilds. ...

Names changes and deletion of files that have been uploaded- Using Vue.js

I attempted to use v-model in order to rename files before uploading them to the system, but unfortunately, it was not successful. As a result, I developed an alternative solution which is functioning perfectly, except for the fact that I am unable to reta ...

Invoke a Python function from C, sending float arrays as parameters and saving the resulting data into them

I'm currently developing an astronomy application that requires reading a CASA MS File in Python. This file is designed to be easy to read, but I also need to work with CUDA for processing. My goal is to save the data from the file as u,v coordinates ...

Is it possible to hide a menu by removing a class when the user clicks outside the menu?

I've come across a lot of information about how to close a menu when clicking outside of it, but my question is, can the following code be simplified to something like if you don't click on #menu > ul > li > a then removeClass open. Can ...

Guide to embed a Google Sheets chart into a WordPress website

I'm looking to include a chart in a wordpress post, using the script generated from google sheets' publish function. When I add the script to a generic HTML page, the chart displays properly. However, when I insert it into a wordpress post, I en ...

Utilizing JSON format for processing HTTP requests in JavaScript with Node.js

I'm working with a snippet that retrieves data in JSON format, but I'm interested in manipulating the data instead of just outputting it to the console. var request = require('request'); var headers = { 'Connection': ' ...

Create a unique Bitcoin address using a derivation scheme

Starting with a derivation scheme that begins with tpub... for the testnet, I am looking to generate bitcoin addresses from this scheme. I also need a method that will work for the mainnet. Is there a library available that can assist me with this task? ...

JavaScript: the battle between anonymous and direct function invocation

Here is an interesting observation: when I assign an anonymous function to the onreadystatechange variable, everything works fine. However, if I try to assign a named function to this variable, it does not work as expected. <script language="Javascrip ...

A method for combining multiple arrays into a single array within a For loop

I am trying to combine multiple arrays of objects into a single array. Here is an example with a transaction array that contains two different arrays: transaction: 0:(3) [{…}, {…}, {…}] 1:(2) [{…}, {…}] I would like the combined result to loo ...

Navigating through a JSON dictionary in Svelte: A step-by-step guide

When working with Svelte, the #each construct allows for easy iteration over array-like objects. But what if you have a JSON dictionary object instead? Is there a way in Svelte to iterate over this type of object in order to populate a dropdown menu? The ...

Executing functions in a loop using Angular

Within my component, there is a foreach loop triggered when a client is selected. Inside this loop, I need to execute a function within the same component. The issue arises with calling the function using `this.functionName()` because 'this' no ...

Error: Validation error encountered while validating recipe: _listId field is mandatory and must be provided

As a newcomer to node.js, I am attempting to create a cookbook restful API using nodejs. The goal is to have a list of recipes where each recipe is associated with a specific list selected by its id. However, I am encountering an issue while trying to retr ...

Having difficulty extracting data from certain tables with Beautiful Soup

I have been utilizing BeautifulSoup for data scraping from the website here. Although there are a total of 9 tables with the same class name, I am only able to extract information from 5 of them. What modifications should I implement in my code to ensure t ...

Tips for resolving the issue of cypress automatically opening a new tab

Recently, I've encountered an issue while using Cypress to perform a test on my website. Every time I click on a button, it redirects me to a new tab, disrupting the flow of my test with Cypress. Despite trying to remove the "target" attribute using t ...

Avoiding conflicts: Using Tabs with Revolution Slider without jQuery interference

I'm running into an issue with the tabs on my website. The revolution slider is working perfectly, but the tab widget seems to be displaying all the tab contents at once instead of each one separately. You can see the problem here: at the bottom of t ...

The removeClass method does not affect the class attribute when using $(this).attr('class'), but only when using $(this).attr('id')

I am currently facing an issue with reducing the size of my jQuery code. The main function is to validate a form - if empty, I want to add a class of 'highlight' or remove it using addClass('highlight') and removeClass('highlight&a ...

Utilizing React, generate buttons on the fly that trigger the display of their respective

Looking for a way to dynamically display 3 buttons, each of which opens a different modal? I'm struggling to figure out how to properly link the buttons to their respective modals. Here's the code I've attempted so far: Button - Modal Code: ...

How can nextJS leverage async getInitialProps() method in combination with AWS S3?

I'm currently facing a challenge with executing an s3.getObject() function within an async getInitialProps() method in a nextJS project. I'm struggling to properly format the results so that they can be returned as an object, which is essential f ...