Organize a collection of objects based on their individual keys

How can an array of objects be grouped based on keys using vanilla JavaScript, especially when dealing with a large number of records like 10000? Here is a sample object to illustrate:

[
 {
  company: "TATA",
  car: "TATA Indica",
  color: "Blue"
 },
 {
  company: "TATA",
  car: "TATA Indica",
  color: "Black"
 },
 {
  company: "TATA",
  car: "Safari",
  color: "Blue"
 },
 {
   company: "Suzuki",
    car: "",
    color: ""
 }
]

The desired output should look like this:

{
   "company": ["TATA", "Suzuki"],
   "car": ["TATA Indica", "Safari"],
   "color": ["Blue", "Black"]
}

Answer №1

One efficient way to tackle this would be utilizing the power of reduce, along with enhancing it further by incorporating Map.

const arr = [{
    company: "TATA",
    car: "TATA Indica",
    color: "Blue",
  },
  {
    company: "TATA",
    car: "TATA Indica",
    color: "Black",
  },
  {
    company: "TATA",
    car: "Safari",
    color: "Blue",
  },
  {
    company: "Suzuki",
    car: "",
    color: "",
  },
];

const result = arr.reduce((acc, curr) => {
  Object.keys(curr).forEach((k) => {
    if (curr[k]) {
      if (!acc[k]) acc[k] = new Set();
      else acc[k].add(curr[k]);
    }
  });
  return acc;
}, {});

Object.keys(result).forEach((k) => (result[k] = [...result[k]]));
console.log(result);

Answer №2

One approach for handling primitive values efficiently is to utilize a combination of Set and Map. The Map data structure can be used for keys, while the Set data structure can be used for values.

const brands = ["Apple", "Samsung", "Google", ""];
const products = ["iPhone", "Galaxy", "Pixel", ""];
const colors = ["Blue", "Black", "Red", "Yellow", ""]
const arr = Array.from({length: 1000}, (v, i) => ({
  brand: brands[i % brands.length],
  product: products[i % products.length],
  color: colors[i % colors.length]
}));

console.time('Process');
const map = new Map();
for(let item of arr) {
  for(let key of Object.keys(item)){
    let keySet = map.get(key);
    if(!keySet){
      keySet = new Set();
      map.set(key, keySet);
    }
    const value = item[key];
    if(value !== '') {
      keySet.add(item[key]);
    }
  }
}
const result = {};
for(let key of map.keys()) {
  result[key] = Array.from(map.get(key));
}
console.timeEnd('Process');
console.log(result);

Answer №3

It appears that the data you are working with has a consistent structure throughout. In this scenario, you can predefine the shape of the final object and then populate it by accumulating the data while checking for non-empty values. One approach is to utilize Map and Set for gathering the data and then transforming it into the desired result object.

const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];

const map = new Map(Object.keys(data[0]).map((k) => [k, new Set()]));

for (const d of data) {
  for (const k of map.keys()) {
    if (d[k] !== '') {
      map.get(k).add(d[k]);
    }
  }
}

const result = {};
for (const k of map.keys()) {
  result[k] = Array.from(map.get(k));
}

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

Interestingly, a seemingly simple implementation surprisingly turns out to be quite efficient (according to @Totati's benchmark). It involves serial calls of map().filter().

const data = [{ company: 'TATA', car: 'TATA Indica', color: 'Blue' }, { company: 'TATA', car: 'TATA Indica', color: 'Black' }, { company: 'TATA', car: 'Safari', color: 'Blue' }, { company: 'Suzuki', car: '', color: '' },];

const result = {};

for (const k of Object.keys(data[0])) {
  result[k] = Array.from(
    new Set(data.map(({ [k]: key }) => key).filter((n) => n !== ''))
  );
}

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

Answer №4

If you want to efficiently store unique values for each key and then convert them back into an array later, one method is to utilize the Set data structure.

const information = [
  {
    category: "Fruit",
    item: "Apple",
    color: "Red",
  },
  {
    category: "Fruit",
    item: "Banana",
    color: "Yellow",
  },
  {
    category: "Vegetable",
    item: "Carrot",
    color: "Orange",
  },
]

let result = information.reduce((accumulator, element) => {
  for (const [property, value] of Object.entries(element)) {
    if (!value) continue

    if (property in accumulator) {
      const set = new Set(accumulator[property])
      set.add(value)
      accumulator[property] = Array.from(set)
    } else {
      accumulator[property] = [value]
    }
  }

  return accumulator
}, {})

console.log(result)

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

MUI: The value you have chosen for the select component is outside the acceptable range - `[object Object]`

I'm currently in the process of developing a custom Select component that offers both single and multi-selection features. Below is how I initialize the components: const vendorList = [ { label: "John", value: "668", } ...

Having trouble loading AngularJS 2 router

I'm encountering an issue with my Angular 2 project. Directory : - project - dev - api - res - config - script - js - components - blog.components.js ...

Displaying error messages for bad requests in a Web API using JSON and AJAX

I need assistance in displaying error messages from my child class on the front end of my website when using a REST client to return an 'ok' response. I have provided my create methods and controller below, any guidance would be greatly appreciat ...

Ionic 3 Storage Timing Explained

I have a scenario where I am trying to load JSON data from storage and display it on the HTML template of my page. However, when I try to do this, I encounter errors suggesting that the information is not yet available upon entering the page. I'm sta ...

Traversing through a arranged associative array

I am working with an array containing positive integer values such as [4, 1, 75, 52, 5, 24]. My goal is to find two values in the array that have the smallest difference. In addition to this, I also need to know the original keys of those two values. To ac ...

Utilize jQuery to extract data from a Steam page in JSON format

Although I have researched extensively on this topic, it is still not functioning as desired. I came across this Steam page in JSON format. My aim is to extract the lowest_price variable without using PHP as I am incorporating it into my Chrome extension. ...

RainTpl: accessing specific array value within loop based on key

After assigning an array for language to tpl, I also assign another array fetched from a database query. Now, I need to print the values from the language array using the keys from the query array by looping through them: $arrayLang = array ( "id" =&g ...

jQuery load fails to fill select dropdown

Upon page load, my code executes a call to mysql to populate a select element with data. This process works smoothly on the initial load or when the page is refreshed. However, I am encountering an issue when attempting to update or repopulate the select e ...

organizing a List<Object> both numerically and alphabetically by the field 'product' in the Object

List<ShipInventoryReportDataVO> lstShipInvData = shipInventoryReportDAO .getShippableInventoryReportData(inputVO, true); ShipInventoryReportDataVO represents my object class and retrieves data from a stored procedure. Within the ShipInventoryRep ...

When a table row is selected, set the OnClick attribute of an input to the value of the TD cell in that row based on

I'm really struggling with this. So, here's the issue - I have a table where rows get assigned a class (selected) when clicked on. Now, there's an input inside a form that needs to redirect to another page when clicked, and it also needs t ...

Troubles with uploading a hefty file

Utilizing the Blazor's InputFile component, I encountered an issue while trying to upload and parse a large Json file from a web view. Upon uploading a 11mb JSON file with approximately 300,000 lines, I received an exception stating that the JSON cont ...

Creating Table Rows on-the-fly

Seeking assistance and guidance from the community, I have modified code from an online tutorial to allow users to dynamically add rows to a table when data is entered in the row above. However, I am facing an issue where I can only insert one additional ...

Set the HTML content as a string in the Html variable, similar to innerHTML but without using JavaScript directly from an external

When working in an embedded ruby (html.erb) file, I encounter a situation where I have a string of HTML such as variable_string = "<p>Some <strong>Content</strong></p>". In JavaScript, we can easily update the DOM with Element.inn ...

Guide on expanding the capabilities of IterableIterator in TypeScript

I am currently working on extending the functionality of Iterable by adding a where method, similar to C#'s Enumerable.where(). While it is straightforward to extend the Array prototype, I am encountering difficulties in figuring out how to extend an ...

Ingesting JSON data from ZIP files into MongoDB using Python

I have a script that goes through a folder to retrieve all .zip files, then proceeds to open each one, extract the JSON file contents, and import them into MongoDB. However, I encountered an error stating the JSON object must be str, bytes or bytearray, n ...

"Integrate a URL segment into the primary URL with the help of AngularJS or JavaScript

One interesting case involves a URL path that is structured in the following way. http://localhost:12534/urlpart1/urlpart2?querystring=140 The challenge here is to replace "urlpart2" with "urlpart3" using either javascript or AngularJS. One approach is t ...

What is the best way to aggregate totals by date in Ruby when working with an array of hashes?

I'm trying to consolidate an array of arrays that represent the number of orders by week. How can I merge these arrays to calculate the total orders for each week? [ [ {:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"1.00"}, {:wee ...

What causes an error when attempting to add a new user to the database?

Currently, I am delving into the world of Mongodb. To kick things off, I initiated by executing npm install --save mongoose uuid within the confines of Terminal. The primary objective of my project revolves around storing user information in the database. ...

Guide on using react-highlight-words to emphasize various keywords using different color schemes

I am currently working on implementing a search feature for my React project. At the moment, I am only required to enter a single keyword and search for it within the text. Once found, I need to extract and display the sentences containing this keyword sep ...

The webservice encountered an issue while trying to interpret the JSON Request coming from a PHP file

I'm working on integrating a webservice into my PHP document. While I've successfully used this webservice with an android app, I am encountering issues when trying to access it through PHP. When I test the webservice using Chrome's advanced ...