Develop an array of objects containing the respective sums of values from an array already present in JavaScript

Consider the array below:

["cat", "dog", "cat", "rabbit", "cat", "lion"]

I am looking to transform this array into an object array that shows the frequency of each element, for example:

[
 { name: cat, count: 3 },
 { name: dog, count: 1 },
 { name: rabbit, count: 1 },
 { name: lion, count: 1 },
]

How would I go about accomplishing this task in Javascript? I typically use the Lodash library, so if there is a straightforward solution using it, feel free to suggest it.

Answer №1

To achieve a frequency map, start by building a map of frequencies based on the array values. Use each value as a key and increment the count in the map accordingly.

The formula for adding a new key is: ((freq[val] || 0) + 1). This means taking the existing count or starting at 0, then adding 1.

Once the map is created, convert it into an array with name/count pairs.

let arr = ["red", "red", "green", "red", "green", "blue"];

let frequencyMap = arr.reduce((freq, val) => {
  return { ...freq, [val]: ((freq[val] || 0) + 1) }
}, {});

let results = Object.keys(frequencyMap).map(key => {
  return { name : key, count : frequencyMap[key] }
});

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


Mini Golf Challenge

Here's a concise one-liner using a mapping function:

const freqArray = (a, fn) => (
  (f) => Object.keys(f).map(k => fn(k, f[k]))
)(a.reduce((m, v) => ({ ...m, [v]: ((m[v] || 0) + 1) }), {}));

let arr = [ "red", "red", "green", "red", "green", "blue" ];
let freq = freqArray(arr, (k, v) => ({ name : k, count : v }));

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


Sorting Magic

You can also sort the results alphabetically by name since the keys are unique, removing the need to sort by count:

const freqArray = (arr, opts) => (
  (freq) => Object.keys(freq).map(key => opts.mapFn(key, freq[key]))
)(
  arr.reduce((m, v) => ({ ...m, [v]: ((m[v] || 0) + 1) }), {})
).sort(opts.cmpFn);

let arr = [ "red", "red", "green", "red", "green", "blue" ];
let freq = freqArray(arr, {
  mapFn: (key, val) => ({ name : key, count : val }),
  cmpFn: (a, b) => a.name.localeCompare(b.name)
});

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

To sort by count in descending order followed by name:

const freqArray = (arr, opts) => (
  (freq) => Object.keys(freq).map(key => opts.mapFn(key, freq[key]))
)(
  arr.reduce((m, v) => ({ ...m, [v]: ((m[v] || 0) + 1) }), {})
).sort(opts.cmpFn);

let arr = [ "red", "red", "green", "red", "green", "blue", "green", "blue", "blue" ];
let freq = freqArray(arr, {
  mapFn: (key, val) => ({ name : key, count : val }),
  cmpFn: (a, b) => (b.count - a.count) || a.name.localeCompare(b.name)
});

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

Answer №2

If you're utilizing the lodash library, you have the option to use _.countBy() in order to tally the occurrences of a specific word, providing you with an object like this as the outcome:

{
  "red": 3,
  "green": 2,
  "blue": 1
}

Once you acquire this object, you can proceed to apply _.map() to restructure it so that the key becomes the value for the name property, and the value becomes the value for the count property:

const arr = ["red", "red", "green", "red", "green", "blue"];

const getFreq = _.flow(
  _.countBy,
  gr => _.map(gr, (count, name) => ({name, count}))
);

console.log(getFreq(arr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

In this scenario, _.flow() is utilized to generate a function which can be employed to group additional arrays if necessary. However, if you just require the final result, the code can be simplified as follows:

const res = _(arr).countBy().map((count, name) => ({name, count})).value();

Answer №3

Utilize Array.reduce method by starting with an empty array. During each iteration, check if an object exists with the current value as the "name", if so, increment the count; otherwise, add a new object:

const arr = ["red", "red", "green", "red", "green", "blue"];

const result = arr.reduce((acc, curr) => {
  const ndx = acc.findIndex(e => e.name === curr);

  if (ndx > -1) {
    acc[ndx].count++;
  } else {
    acc.push({
      name: curr,
      count: 1
    });
  }
  
  return acc;
}, []);

console.log(result);

Answer №4

Utilizing the countBy() function from lodash for a clear and straightforward approach.

const colors = ["red", "red", "green", "red", "green", "blue"];
const result = [];

for ( [key, value] of Object.entries(_.countBy(colors)) ){
  result.push( { 
    name : key,
    count: value
  })
}

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

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

Executing onClick event in RiotJS upon page load

As I develop a table application using RiotJS, I consistently encounter an issue with the onclick event. Whenever I attempt to utilize the <tag onclick={somefunction}> I face unpredictable behavior. Sometimes, it will excessively call the function ...

Creating an array from a string within an array

I've been working with an array of JSON objects lately. Take a look at this example: arr = ["{"topic":"none","url":"https://google.com"}"] In addition, I also have the string representation of this array. How can I reverse this process and convert ...

What is the process for using Discriminators, the Mongo DB API, and Mongoose to insert data into Cosmos DB?

Issue Overview I am currently facing a challenge in writing documents to my Cosmos DB using the Mongo DB API and Mongoose for Object Modeling. To optimize costs, I aim to store all documents in a single collection by utilizing Discriminators. The project ...

Troubleshooting Hover Problem with D3 Chord Example on Internet Explorer 11

I came across an interesting tutorial on how to create chord diagrams in D3, which I'm currently experimenting with. The tutorial can be found at One example that caught my attention is about hair color preferences. When you hover over a group on the ...

Alter the jQuery in an Iframe to make changes to the parent document

Exploring a unique use case where I am sandboxing multiple JavaScript libraries into hidden iframes. Within the website, there are various widgets, all sourced from the same domain, that might require different versions of JS libraries. To avoid global con ...

Is there a way to split a string into equal chunks of characters in JavaScript?

What is the process for splitting a string into segments every X number of characters? To put it in perspective, if I have an extremely lengthy string and want to divide it into parts of 1000 characters each, how can this be achieved when the content varie ...

Ensuring Secure API Request Distribution

Currently, I am experimenting with distributed API requests. In PHP, I am developing a website that allows users to make requests on behalf of the server. The objective is to distribute these requests among users to maintain scalability even in high-traffi ...

What is the best way to automatically reference a growing collection of data entries?

In my dataset, I have a column that contains a list of unique IDs. There are multiple tabs that utilize this list to display various related data for each ID. Currently, whenever a new ID is added, I have to manually enter it in each tab to access the da ...

Invoking AJAX function post readystatechange

Currently, I am in the process of making an Ajax call to a server and attempting to invoke another function once the response is ready (readystatechanged). As of now, there isn't any serverside code implemented. Surprisingly, Chrome and Firefox encoun ...

Modify the JavaScript window.navigator

I am attempting to modify window.navigator, but am facing difficulties in doing so: -- [10:40:28.802] window.navigator['buildID']; [10:40:28.811] "20121129162756" -- [10:40:47.225] window.navigator['appCodeName'] = "I want to change it ...

retrieve an array inside the doInBackground function

Here is the code snippet that I have been working on: private class GetMovie extends AsyncTask<String, Void, String[]>{ protected String[] doInBackground(String...arg0){ // Creating service handler object ServiceHandler sh = ne ...

Transferring SQL-generated JSON object from PHP to JavaScript

Seeking assistance with passing a JSON object from PHP to Javascript. The object is populated from an SQL Database using the following PHP code snippet. <?php $conn = mysql_connect("localhost","root",""); if(! $conn ) { die('C ...

There are certain CSS3 properties that are not being accounted for in the CSS min

I've incorporated several newer CSS3 properties in my stylesheet, but I'm concerned that the minification tool I'm currently utilizing may not be capturing all of these properties: .big-blue-button:hover { text-decoration: none; bac ...

Navigate to a new page seamlessly without the need for refreshing the current page in Django

Is there a way to navigate to another page without refreshing after clicking on a link to a different URL? For example, if I have a list of books displayed and I click on one of the books, can it redirect me to the selected book page without reloading the ...

Using Regex with JavaScript while ignoring letter case

I am trying to extract a query string from my URL using JavaScript, and I need to perform a case-insensitive comparison for the query string name. In order to achieve this, here is the code snippet that I am currently using: var results = new RegExp(&apos ...

Guide to displaying the output of a JS calculation in a Bootstrap modal dialog box

I have a HTML and JavaScript code that determines the ideal surfboard for the user based on their input data (style, experience, height, weight) and displays the recommended surfboard type. Here is the initial code snippet I attempted to use: function c ...

Ensuring the safe transmission of NodeJS applications

Query: Is it possible to distribute NodeJS apps as binaries by compiling the .js app through V8 into its native binary form for client distribution, assuming total access to the NodeJS server? Or are we limited to just minifying the code? Motivation: Our ...

AngularJS - Calculate multiple currencies

I need to calculate the product of a value and months. For the input value, I am utilizing a Jquery Plugin to apply a currency mask. Unfortunately, the calculations are not functioning properly with this plugin. My goal is to multiply the value, includin ...

How can I use Jquery to animate an element to the right edge of the window?

Exploring the realm of jQuery animations, I am currently experimenting with animating a div to the right side of the window while changing its color using jQuery UI. This is just a fun project without any specific purpose in mind. Below is the code snippet ...

Tips for incorporating CSS styling into imported joint js bpmn elements

Our dashboard now includes components from a company supplying us with Business Process Model And Notation (BPMN) json objects. We bring in the BPMN json object using "fromJSON()" onto the joint.dia.Paper. Everything is functioning properly. However, I ...