What is the best way to transform an array of objects in JavaScript?

I'm working with an array of objects that I need to transform into a table by pivoting the data. In other words, I am looking to generate a new array of objects with unique titles and nested arrays of key-value pairs. Can someone please assist me in achieving this task? Below, you'll find the original array and the desired array:

Original Array:

[
{title: "Title1", value1: "value1", value2: "value2"},
{title: "Title2", value1: "value1", value2: "value2"},
{title: "Title1", value1: "value1", value2: "value2"},
{title: "Title3", value1: "value1", value2: "value2"},
{title: "Title2", value1: "value1", value2: "value2"},
{title: "Title1", value1: "value1", value2: "value2"},
{title: "Title3", value1: "value1", value2: "value2"},
{title: "Title1", value1: "value1", value2: "value2"},
]

Desired result:

[
{title: "Title1", values: [{value1: "value1"}, {value2: "value2"}]},
{title: "Title2", values: [{value1: "value1"}, {value2: "value2"}]},
{title: "Title3", values: [{value1: "value1"}, {value2: "value2"}]},
]

Thank you in advance for any help or suggestions.

Answer №1

Using a simple array reduce function can be beneficial in this scenario.

let info = [{
  title: "Title1",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title2",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title1",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title3",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title2",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title1",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title3",
  value1: "value1",
  value2: "value2"
}, {
  title: "Title1",
  value1: "value1",
  value2: "value2"
}];

let transformedData = info.reduce((prev, current) => {
  let existingItem = prev.find(item => item.title === current.title);

  if (existingItem)
    existingItem.values.push(current)
  else
    prev.push({
      title: current.title,
      values: [current]
    });

  return prev;
}, []);

console.log(transformedData);

Resources Utilized

Reduce function

Find method

This method can be adjusted to pivot based on any field specified, with the inclusion of error handling for cases where the field does not exist:

let pivotByField = (key, info) => info.reduce((prev, current) => {
  let existingItem = prev.find(item => item[key] === current[key]);

  if (existingItem) {
    existingItem.values.push(current);
  } else {
    let newEntry = {
        values: [current]
    }

    newEntry[key] = current[key];

    prev.push(newEntry);
  }

  return prev;
}, []);

UPDATE I misunderstood the desired output format initially, but the reduce function can be adjusted to meet that requirement.

Answer №2

You can utilize a hash table to group data using thisArg in conjunction with Array#forEach.

var data = [{ title: "Title1", value1: "value1", value2: "value2" }, { title: "Title2", value1: "value1", value2: "value2" }, { title: "Title1", value1: "value1", value2: "value2" }, { title: "Title3", value1: "value1", value2: "value2" }, { title: "Title2", value1: "value1", value2: "value2" }, { title: "Title1", value1: "value1", value2: "value2" }, { title: "Title3", value1: "value1", value2: "value2" }, { title: "Title1", value1: "value1", value2: "value2" }],
    grouped = [];

data.forEach(function (item) {

    // check if title is not in hash table
    if (!this[item.title]) {

        // if not, create new object with title and values array
        // and assign it with the title as hash to the hash table
        this[item.title] = { title: item.title, values: [] };

        // add the new object to the result set, too
        grouped.push(this[item.title]);
    }

    // create a new object with the other values and push it
    // to the array of the object of the hash table
    this[item.title].values.push({ value1: item.value1, value2: item.value2 });
}, Object.create(null)); // Object.create creates an empty object without prototypes

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №3

    var originalArray = [
      {title: "Title1", value1: "value1", value2: "value2"},
      {title: "Title2", value1: "value1", value2: "value2"},
      {title: "Title1", value1: "value1", value2: "value2"},
      {title: "Title3", value1: "value1", value2: "value2"},
      {title: "Title2", value1: "value1", value2: "value2"},
      {title: "Title1", value1: "value1", value2: "value2"},
      {title: "Title3", value1: "value1", value2: "value2"},
      {title: "Title1", value1: "value1", value2: "value2"},
    ];
    var newArray = [];

    for(var i = 0; i<originalArray.length; i++){
      var object = {};
      object.title=originalArray[i].title;
      var values = [];
      values.push({value1: originalArray[i].value1});
      values.push({value2: originalArray[i].value2});
      object.values= values;
      newArray.push(object);
    }

This code appears to be functional. However, the presence of duplicate titles in the original array may result in unintended behavior. If the duplications were intentional for demonstration purposes, then the code should work as intended. Otherwise, a different approach would be required to handle duplicate titles.

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

JavaScript - The left dropdown menu stubbornly remains visible when clicked in white space, unlike the right dropdown which disappears as expected. Puzzled by this inconsistency

Whenever I click on the selection criteria box, a dropdown menu appears. Clicking on the white space or the data table button makes the drop-down menu disappear, which is good. However, when I perform the same action for 'choose data table,' the ...

What steps should I take to generate a stylized date input in javascript?

Looking to dynamically create a date string in JavaScript with the following format: dd-MMM-yyyy Need the dd part to change between 1 and 29 each time I generate the variable within a loop Month (MMM) should be set as Jan ...

Utilize Vue to access and read a file stored in the current directory

I am attempting to retrieve data from a text file that is located in the same directory as my .vue file. Unfortunately, I am encountering an issue where the content of the text file is not being displayed in both Chrome and Firefox. Instead, I am seeing th ...

Navigating between different route groups using redirection: a step-by-step guide

My project folder structure is organized like this: app (app) dashboard page.tsx page.tsx layout.tsx (auth) login ...

Steps for utilizing Bazel to compile TypeScript

Calling all Bazel (Blaze) experts: I'm curious about the best method for integrating Bazel as a build system for cutting-edge web applications built in Typescript. Is there a preferred setup or perhaps a template that demonstrates this integration? T ...

Having trouble receiving the response from PHP after making an AJAX request

Can you help me figure out why I'm not receiving any return value from the ajax data post? Take a look at my code and let me know where I might be going wrong. Here is a snippet of my jQuery code: $("#btnlogin").click(function(){ var email = $( ...

Define the position of a scrolled area within an HTML document to create a

In my current project, I have a scrollable area that highlights the selected div in gray. The HTML is written using Ember (hbs) and includes code to handle this functionality. Below is an example of how the div looks: https://i.sstatic.net/T2Lur.png Here ...

Best method for reverting react-native to previous version

Here's the dilemma I'm facing: I had a functional version of a react-native project that was running smoothly and committed to my git repository. Deciding to upgrade from react-native 0.26.3 to 0.28 led me into a tangled web of dependencies, so ...

Utilizing Ajax to dynamically update the content of a div element

As a newcomer to Ajax, I am trying to use xmlhttprequest to dynamically change the content of a div by fetching HTML from different URLs. However, my code doesn't seem to be working as expected. Can someone help me identify what I might be doing wrong ...

PHP query Ajax navigation

UPDATED I have made progress with processing both menus in "process.php" and displaying the queries in index.php. process.php <?php $menu1 = $_POST["menu1"]; $menu2 = $_POST["menu2"]; if($menu1 == 0) { $sql = "SELECT * FROM Language WHERE ID = " ...

"Oops! Vite seems to be facing an issue as RefreshRuntime.injectIntoGlobalHook function is

Our CRA react app has been transitioned from webpack to Vite. Problem: When running the application locally in production mode, I encounter the following error: 1. Uncaught TypeError: RefreshRuntime.injectIntoGlobalHook is not a function at (index):6:16 ...

Retrieving coordinates from an array

I am currently working on developing a function to locate the array coordinates that correspond to a predefined number: Below is the code I have so far: public static int findCoord(double[][] array, double target) { int[] coordinates = {0, 0}; for ...

How can we stop the Replace function from replacing spaces as well?

When I trigger a paste event in an input field, I have a method that replaces all special characters. However, it is also removing empty spaces between words. How can I prevent this from happening? checkSpecialCharacters(){ let value = this.form.get(&q ...

Linking promises to eliminate nesting

Hi everyone, I am currently working on chaining promises in my code. The initial HTTPS call returns an array of URLs successfully. After that, I loop through them to obtain a JSON object for each one. I am wondering if there is a way to reduce nesting in ...

Removing an element from an array of objects in Javascript

My situation involves an array containing objects: var items = [{ id: 1, text: "test1" }, { id: 2, text: "test2" }, { id: 3, text: "test3"}]; In addition, I have this specific object: var itemToRemove = { id: 2, text: "test2" }; My objective is to veri ...

Press the smiley icon and drag it into the designated input box

Is there a way to select and copy a smiley/emoji from a list and paste it into an input field? Although the Inspect Element Q (console log) shows that the emoji is being clicked, I am having trouble transferring it to the input field. Here is the HTML cod ...

Arranging a multidimensional array based on key value pairs in PHP

My array contains states with key-value pairs representing companies. I need to sort the array for each state in descending order based on the company's value, with the highest value company listed first and the lowest value company listed last. arr ...

Searching for values in JSON using jQuery's autocomplete feature

I have implemented jquery autocomplete with a json request in my code. Here is the code snippet for the autocomplete feature: $("#company_name").autocomplete({ source: function( request, response ) { $.ajax({ url: "https://ur ...

Troubleshooting issues with jQuery `.live()` event not triggering as expected

In a project I am working on, I have implemented complex AJAX functionality to fetch inner page content from a WordPress blog. Due to the dynamic nature of the site, where the DOM is replaced after page load via AJAX, I have opted to use jQuery's .liv ...

Presenting a 24-column data table fetched from MySQL and integrated into a webpage through JavaScript DataTables

Greetings everyone! I have a query regarding Javascript DataTables and how it displays data from a MySQL table. Here's the MySQL query in question: select LOT_LOCATION, `Zone Attribute`, a.LOTID, Design_ID, ifnul(Board_ID,'') as Board_ID1, ...