Use lodash to categorize an array of objects into distinct groups

const readings = [
  { location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'1' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  {  location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'3' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  { location: { lat: '28.4', lng: '21.5' }, vehicle: 'sdkhf', id:'5' },
];

The task at hand is to group the array of objects above based on their location property.

The desired outcome consists of an array of objects that include the location and points (an array of objects with the same location).

This grouping operation can be achieved using either lodash or the array reduce method.

Answer №1

The _.groupBy() method takes a callback function as an argument to determine how to group the elements. One way to create unique keys for grouping is by combining the values of lat and lng using a template string.

const data = [{"location":{"lat":"21.4","lng":"23.5"},"name":"John","id":"1"},{"location":{"lat":"22.4","lng":"25.5"},"name":"Jane","id":"2"},{"location":{"lat":"21.4","lng":"23.5"},"name":"James","id":"3"}];

const groupedData = _.groupBy(data, ({ location: { lat, lng} }) => `${lat}-${lng}`);

console.log(groupedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

Answer №2

To group the readings by location and then convert the result into an array of objects with location as the key and points list as the value, you can utilize the .reduce method:

const readings = [
  { location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'1' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  {  location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'3' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  { location: { lat: '28.4', lng: '21.5' }, vehicle: 'sdkhf', id:'5' },
];

//group by location
let res = _.reduce(readings, (acc,item) => {
  const { location: { lat, lng } } = item;
  const key = `${lat}-${lng}`;
  const prev = acc[key];
  if(!prev) acc[key] = [item];
  else acc[key].push(item);
  return acc;
}, {});
//transform to array of objects location-points
res = _.map(_.entries(res), ([location,points]) => ({ [location]: points }));

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

Answer №3

Utilizing Lodash's groupBy function can simplify the process for you. All you need to do is provide a comparison function, like this:

import _ from "lodash";

const dataArr = [
  {
      position: {
          x: '21.4',
          y: '23.5'
      },
      item: 'abc',
      num:'1'
  },
  {
      position: {
          x: '22.4',
          y: '25.5'
      },
      item: 'abc',
      num:'2'
  },
  {
      position: {
          x: '21.4',
          y: '23.5'
      },
      item: 'abc',
      num:'3'
  },
  {
      position: {
          x: '22.4',
          y: '25.5'
      },
      item: 'abc',
      num:'2'
  },
  {
      position: {
          x: '28.4',
          y: '21.5'
      },
      item: 'abc',
      num:'5'
  },
]

const getPos = ({ position }) => `${position.x}/${position.y}`
const groupedObj = _.groupBy(dataArr, getPos)
const groupedArray = Object.values(groupedObj)

Answer №4

Utilizing the #array.reduce Method

While other solutions may rely on lodash, you can effortlessly accomplish this task using the .reduce() method.

The crucial aspect here is to generate the key in a specific format.

const key = `lat.${curr.location.lat}-lng.${curr.location.lng}`

You are free to choose any format you prefer, as long as it's based on the location.lat & location.lng, and the key must be a string, not an object.

const readings = [
  { location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'1' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  {  location: { lat: '21.4', lng: '23.5' }, vehicle: 'sdkhf', id:'3' },
  { location: { lat: '22.4', lng: '25.5' }, vehicle: 'sdkhf', id:'2' },
  { location: { lat: '28.4', lng: '21.5' }, vehicle: 'sdkhf', id:'5' },
];

var result = readings.reduce((acc, curr) => {
    const key = `lat.${curr.location.lat}-lng.${curr.location.lng}`
    acc[key] ??= {[key]: []};
    acc[key][key].push(curr);

    return acc;
  }, {})

console.log(Object.values(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

`You may encounter a error message indicating "ReferenceError: <package> not defined" even after successfully installing the package.`

After successfully running the command npm install chevrotain in a specific folder, I checked the version with npm -v chevrotain, leading me to get 8.1.2. In my package.json file, I have "chevrotain": "^10.1.2" listed under dependencies ...

Loop through JSON data using jQuery for parsing

Here is the code snippet I have included below, which is a part of a larger code base: <html> <head> <style> #results{margin-top:100px; width:600px; border:1px solid #000000; background-color:#CCCCCC; min-height:200px;} </style> & ...

Encountering an error of "Cannot access property 'PluginKey' of undefined" while utilizing @toast-ui/editor in a JavaScript project

Struggling with integrating the @toast-ui/editor into my native JavaScript project. The editor is not displaying due to this error message: Cannot read property 'PluginKey' of undefined" This error is specifically within the toastui-editor ...

Retrieve the user-inputted data from an Electron BrowserView's input field

Consider this scenario where a BrowserWindow is set up with specific security settings, including enabling the webviewTag: true for project requirements. let webPrefs = { plugins: false, nodeIntegration: false, nodeIntegrationInWorker: false, ...

What is the recommended approach for embedding scripts within Angular templates?

I am working on an Angular SPA that consists of multiple tabs, each served by templates. Depending on the tab, different scripts (both local and CDN) are required. Therefore, I am looking for a way to load these scripts only when they are needed, which mea ...

Challenges integrating Jquery with Flask

When attempting to add an HTML element using jQuery, I encountered an exception from Flask: jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'static' The string seems correct, but I'm unsure about what the issue ...

Interactive Button Animation using Three.js

After importing a Mesh element into three.js from an fbx file, I am looking to enhance it with an effect similar to that of a clickable button. I am aiming to achieve the same pushable button effect as demonstrated in the first button style found on http ...

The response detail error code 2 indicates that the post method API body check has failed within the Agora REST API, resulting in

const Authorization = `Basic ${Buffer.from(`${config.CUSTOMERID}:${config.CUSTOMER_SECRET}`).toString("base64")}`; const acquire = await axios.post(`https://api.agora.io/v1/apps/${config.agoraAppId}/cloud_recording/acquire`,{ ...

Deleting a model using RestAPI and referencing another model

UPDATE: My professor just advised me to access the driver only from within the admin, not from the admin. Currently, I am developing a project that involves using restAPI's, and one of the requirements is that an admin should be able to delete a driv ...

ng-include failing to retrieve file name containing UTF-8 character

I encountered an issue with the ng-include directive in the code snippet below. The file name it's trying to access contains a special character, specifically an ñ, resulting in a not found error being displayed. <div ng-include="'{{mainCtrl ...

Creating bidirectional data binding in JavaScript with the createElement render function for Vue components

Transitioning my code from the template file to the render function is posing a challenge for me. Currently, I have the following HTML snippet: :open.sync="state" I'm unsure of how to convert this into JavaScript. How can I incorporate this into the ...

Displaying Sweetalert2 textarea inputs in an email

How can I capture the user inputs from a textarea in my code? Here are the details: https://i.sstatic.net/trG1E.gif This is my JavaScript code: $('#sad').on('click', function() { const sad = $('#sad').val(); con ...

Angular project icons not displaying in the browser

My current project in Angular was functioning properly until recently. I am facing an issue where the images are not being displayed on the browser when I run ng serve, resulting in a 404 error. Interestingly, everything else seems to be working fine witho ...

Error Encountered when Making Cross-Origin Ajax Request Using jQuery

I am currently working on implementing a cross-domain Ajax request to an API. Utilizing jQuery for making the call, I am attempting to extract specific items from the response. Below is the code for the request: $.ajax({ type: 'POST', u ...

Generating a chart using solely the existing data components (values)

I have the following arrays: const elements = ['12345', '12346', '12347', '12348', '12349', '12350']; const fruits = ['Apple', 'Ball']; I want to create a Map using array ele ...

Displaying JSON data using Jquery

I am currently trying to fetch a JSON response and display it in a div ... I have written a script for the same script $('select#mes').on('change',function(){ var valor = $(this).val(); var route = "http://localhost/UJOBB/ ...

Retrieve a distinct set of values from one column depending on the values in another column

In order to streamline our software inventory process, I have compiled a comprehensive list of applications running on all assets such as servers, notebooks, and desktops. The table consists of two columns - Column A contains the names of every asset, whil ...

The Vue.js error message "Unable to access property 'array_name' as it is undefined" indicates an issue with

I'm currently working on fetching data using Axios requests and storing it in an array. Below is the code I have been using: props: [ 'products', ], data: function () { return { algolia: '', pro ...

Revamp the HTML page by automatically refreshing labels upon every Get request

My HTML webpage requires real-time updates for one or more labels. To achieve this, I have incorporated CSS and JS animations into the design. Currently, I am utilizing Flask to handle all the calls. I face a challenge where I need to consistently update ...

Google Maps API now offers the ability to generate directions with up to 500 waypoints

I am facing a challenge with displaying a route on Google Maps using an array of 500 waypoints extracted from a GPS route. Google Maps is unable to create a direction or route with more than 23 waypoints, making it difficult to replicate the original GPS ...