Utilizing lodash for effective grouping

I have a collection of objects that looks like this:

var information = [
  {
    "quantity": 1, 
    "make": "ALFA ROMEO", 
    "model": "GIULIETTA DIESEL - 2010"
  }, 
  {
    "quantity": 2, 
    "make": "AUDI", 
    "model": "A1 DIESEL"
  }, 
  {
    "quantity": 1, 
    "make": "AUDI", 
    "model": "A1 SPORTBACK DIESEL"
  }, 
  {
    "quantity": 2, 
    "make": "AUDI", 
    "model": "A3 DIESEL - 2012"
  }, 
  {
    "quantity": 3, 
    "make": "Volkswagen", 
    "model": "Golf"
  }, 
  {
    "quantity": 3, 
    "make": "Ford", 
    "model": "Escord"
  }, 
  {
    "quantity": 2, 
    "make": "Opel", 
    "model": "Zafira"
  }
]

I am looking to group by the data based on the make attribute and then identify the top three makes with the highest quantity. Any remaining makes will be categorized as "Other".

An example output I desire is:

var result = [
    {
       "brand": "Audi",
       "count": 5
     },
     {
       "brand": "Volkswagen",
       "count": 3
     },
     {
       "brand": "Ford",
       "count": 3
     },
     {
       "brand": "Other",
       "count": 3
     }
]

I'm seeking guidance on how to approach this task. Any suggestions?

Answer №1

How to Group and Sum Data in JavaScript

To group and sum data using lodash, start by initiating a chain with _.groupBy() based on the make. Next, use _.map() to map the results and then utilize _.sumBy() to sum the 'count' properties. Convert back to an array with _.values(), sort it in descending order using _.orderBy(), and finalize the chain with _.value(). Split the results into 2 arrays and calculate the sum of the 2nd array (the lowest counts) using reduce:

var data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

var counts = _(data)
  .groupBy('make')
  .map(function(g, key) { return {
      make: key,
      count: _.sumBy(g, 'count')
  };})
  .values()
  .orderBy('count', 'desc')
  .value();
  
var result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce(function(s, { count }) { return s + count; }, 0)
})
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Using ES6

If you prefer using ES6, iterate through the data with Array#reduce, gather all the make count values into a Map, retrieve the map values iterator, spread them to obtain an array, and then sort it in descending order. Divide the results into 2 arrays and calculate the sum of the 2nd array (the lowest counts) using reduce:

const data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

const counts = [...data.reduce((m, { make, count }) => {
  const item = m.get(make) || { make, count: 0 };
  
  item.count += count;

  return m.set(make,  item);
}, new Map()).values()].sort((a, b) => b.count - a.count);

const result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce((s, { count }) => s + count, 0)
})

console.log(result);

Answer №2

To achieve this task, you can utilize a combination of lodash's groupBy and sumBy functions.

let result = _.chain(data)
        .groupBy("make")
        .map((element, id) => ({
            make: id,
            count: _.sumBy(element, 'count'),
        }))
        .value();

console.log(result);

[
  {
    "make": "ALFA ROMEO",
    "count": 1
  },
  {
    "make": "AUDI",
    "count": 5
  },
  {
    "make": "Volkswagen",
    "count": 3
  },
  {
    "make": "Ford",
    "count": 3
  },
  {
    "make": "Opel",
    "count": 2
  }
]

Answer №3

To achieve the desired outcome using vanilla JavaScript, one can implement a hash table to aggregate data based on the same 'make', followed by sorting the resulting array. The next step involves summing up all counts at the end of the result set until reaching the desired length.

var data = [{ count: 1, make: "ALFA ROMEO", model: "GIULIETTA DIESEL - 2010" }, { count: 2, make: "AUDI", model: "A1 DIESEL" }, { count: 1, make: "AUDI", model: "A1 SPORTBACK DIESEL" }, { count: 2, make: "AUDI", model: "A3 DIESEL - 2012" }, { count: 3, make: "Volkswagen", model: "Golf" }, { count: 3, make: "Ford", model: "Escord" }, { count: 2, make: "Opel", model: "Zafira" }],
    hash = Object.create(null),
    result = [];

data.forEach(function (car) {
    if (!hash[car.make]) {
        hash[car.make] = { make: car.make, count: 0 };
        result.push(hash[car.make]);
    }
    hash[car.make].count += car.count;
});

result.sort(function (a, b) {
    return b.count - a.count;
});

while (result.length > 4) {
    result.push({ make: 'Other', count: result.pop().count + result.pop().count });
}

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

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

JQuery slideshow code is unable to operate when multiple slideshow instances are present

I have been trying to enhance my slideshow code to display multiple slideshows simultaneously. The current code successfully selects and adds/removes the active class for two slide shows, but it fails to smoothly transition between slides after one loop. ...

Ensuring seamless mobile compatibility across all browsers

Functionality: An essential aspect of the web app is its compatibility with all mobile web browsers. This requires the development to be responsive and work seamlessly on various platforms. Steps taken so far: I have made adjustments to the CSS, along w ...

Encountering a StaticInjectorError in Angular 5.0

When I try to open the Dialog by clicking a button, I encounter the following error: ERROR Error: StaticInjectorError(AppModule)[UsertableComponent -> MatDialog]: StaticInjectorError(Platform: core)[UsertableComponent -> MatDialog]: ...

React component is not properly updating the state setter value

useState() is unable to store file objects. I have included comments within the code snippet below to clarify the issue: const [file, setFile] = useState<File>() const onChange = async ( imageList: ImageListType, addUpdateIndex: number[] | ...

Using jQuery to add the name of a file to FormData and fetching it in a PHP script

I've been working on a JS code snippet dedicated to uploading images based on their file paths: var data = new FormData(); data.append('fileName', fileName); data.append('file', file); $.ajax({ url : dbPath + "upload-file.php" ...

An array is not just a mere collection of elements

I have an object that resembles an array var items = [ { started_time: 2017-05-04T12:46:39.439Z, word: 'bottle', questionId: '161013bd-00cc-4ad1-8f98-1a8384e202c8' }, { started_time: 2017-05-04T12:47:26.130Z, word: &apo ...

Having trouble navigating through filtering in JavaScript using Node and Express?

After experimenting with different methods, I noticed that when using (age => age.Book === book && age.Chapter === 1) as my filter criteria, everything works perfectly. However, when I try using (age => age.Book === book && age.Chapt ...

Alter the style of a div by clicking on a button

Can the background image of a div be changed by selecting a button outside of the div? For example: HTML <div id="change"></div> <div id="buttons"> <button class="button1">this</button> <button class="button2"> ...

When attempting to use JSON.parse, it returns an undefined value

When using PHP to create JSON data and retrieving it through AJAX, why does JSON.parse return an "undefined" object? PHP CODE $emparray = array(); while($row =mysqli_fetch_assoc($result)) { $emparray[] = $row; } echo json_encode($emparray); AJ ...

Updating an Element in an Array with Mongoose

Is there a more efficient way to update an existing element in an array without fetching the database multiple times? If you have any suggestions, I would greatly appreciate it. Thank you! const updateStock = async (symbol, webApiData) => { try { ...

JavaScript-generated buttons fail to trigger VueJS functions

I have a function that creates buttons for each item in a list, and each button is supposed to execute a function in the App.vue file when clicked. The issue I am facing is that neither the onclick nor the v-on:click methods are functioning as expected. ...

An unusual problem encountered with JSON and PHP

Is there a specific reason why a JSON string fails to be evaluated (transport.responseText.evalJSON();) on the server but works fine on my local setup? I'm making a simple AJAX request like this: new Ajax.Request( this.saveUrl, { ...

Transforming Javascript code using regular expressions into C#

Currently, I am facing a challenge while trying to translate some Javascript code into .NET. Despite my efforts, I have not been able to get it right. The task at hand involves converting paths like /test/:value1/:value2 in Express for NodeJS to a regular ...

Preserve the wpColorPicker selection using personalized knockout bindings

Utilizing wpColorPicker and knockout, my goal is to update the color picker value in my observable and then store it in the database as JSON. While other elements successfully update and save, there seems to be an issue with my custom binding for the data ...

Retrieving parameters from the URL in Angular

I'm facing an issue with my app. I am currently using a factory to manage data for two controllers. When I click on a link that redirects me to another view with a specific URL, I want to reuse the last tag in the URL by slicing it like this: window. ...

Developing a cookie to prevent repeat voting in a survey

I have developed a basic [voting form] by utilizing jQuery AJAX and JSON. My goal is to implement a Cookie system that prevents users from voting more than once. Below is the code snippet I am working with. As someone who is new to both Cookies and jQuery ...

What is the best way to transform a ternary operation into an Enum Map with custom properties

I'm faced with the challenge of styling a button based on the selection made in a select box. The code snippet I have currently is as follows: const buttonStyles = { backgroundColor: buttonStyle === 'Black' ? colors.interactiveForeground ...

Running a PHP script within an HTML file without the need to refresh the page

I need to execute a PHP File that was embedded in a div within my HTML code. The main page consists of a form and a table. The form adds rows to the MySQL table, while the table dynamically displays the content of the MySQL table. I am trying to find a way ...

How to incorporate "selectAllow" when dealing with dates in FullCalendar

I've been attempting to restrict user selection between two specific dates, but so far I haven't been able to make it work. The only way I have managed to do it is by following the routine specified in the businessHours documentation. Is there a ...

What is the process for syncing ng-model with external data sources?

Here is a question that I have pondered: Let's consider the HTML code snippet below: <div id="container" ng-controller="Controller"> <my-tag ng-model="values"></my-tag> </div> Now, take a look at the controller defined a ...