Applying reduce method for accessing object information within an array and transforming its structure

In my data structure, I have a list of deliveries that includes different cities and the number of units delivered to each city:

var deliveries = [{
    location: "Chicago",
    units: 10
}, {
    location: "San Francisco",
    units: 5
}, {
    location: "Miami",
    units: 2
}, {
    location: "San Francisco",
    units: 13
}, {
    location: "San Francisco",
    units: 2
}, {
    location: "Chicago",
    units: 16
}, {
    location: "Miami",
    units: 1
}];

I want to be able to query any city in the list and retrieve the number of times it appears along with the total units delivered to that city. The code I currently use for this purpose is:

function getData(arr, city) {
    var numberOfdeliveries = 0;
    var totalUnitsDelivered = 0;

    arr.forEach(function(val, index, arr) {
        if (val.location === city) {
            numberOfdeliveries += 1;
            totalUnitsDelivered += val.units

        }
    })
    return "number of deliveries: " + numberOfdeliveries + ". Total units:" + totalUnitsDelivered
}

getData(deliveries, "San Francisco"); // number of deliveries: 3. Total units:20

This function works accurately.

However, I am interested in exploring if using reduce can provide an array containing all cities with their respective delivery counts and total units. The desired output should resemble:

[{
    "Chicago": 2,
    units: 26
}, {
    "San Francisco":20,
    units: 5
}, {
    "Miami": 2,
    units: 3
}];

Thus far, my attempts have resulted in an object displaying only the count of appearances of each city:

var deliveries = [{
    location: "Chicago",
    units: 10
}, {
    location: "San Francisco",
    units: 5
}, {
    location: "Miami",
    units: 2
}, {
    location: "San Francisco",
    units: 13
}, {
    location: "San Francisco",
    units: 2
}, {
    location: "Chicago",
    units: 16
}, {
    location: "Miami",
    units: 1
}];

var answer = deliveries.reduce(function(obj, val, index, all) {
    if (!obj[val.location]) {
        obj[val.location] = 1
    } else {
        obj[val.location]++
    }

    return obj

}, {})

console.log(answer);  //{ Chicago: 2, 'San Francisco': 3, Miami: 2 }

Answer №1

To optimize this code, consider using a result array along with a hash table to keep track of references to elements in the result array.

let orders = [{ product: "Apple", quantity: 10 }, { product: "Banana", quantity: 5 }, { product: "Orange", quantity: 2 }, { product: "Banana", quantity: 13 }, { product: "Banana", quantity: 2 }, { product: "Apple", quantity: 16 }, { product: "Orange", quantity: 1 }],
    groups = orders.reduce(function (hash) {
        return function (result, item) {
            if (!hash[item.product]) {
                hash[item.product] = {};
                hash[item.product][item.product] = 0;
                hash[item.product].quantity = 0;
                result.push(hash[item.product]);
            }
            hash[item.product][item.product]++;
            hash[item.product].quantity += item.quantity;
            return result;
        };
    }(Object.create(null)), []);

console.log(groups);

Answer №2

If you're going to run this query multiple times, it would be more efficient to map your data to a hashmap object using cities as the keys

var cities ={};
deliveries.foreach(function(item){
   var cityObj = cities[item.location] ?  cities[item.location] :{units:0, count:0}

   cityObj.units += item.units;
   cityObj.count ++;

});

This will result in something like:

{ "New York" :{units: 8, count:3},
  "Los Angeles":{units: 6, count:2}
} 

Then, when you require the values:

var city="New York",
    units = cities[city].units;

Answer №3

Although Nina technically provided an answer, I found charlietfl's idea of using a hash map to be more effective (despite their code not working). Intrigued, I decided to implement my own hash map using the reduce method. While I ultimately awarded the answer to Nina for being "correct," here is the solution I crafted:

var deliveries = [{
    location: "Chicago",
    units: 10
}, {
    location: "San Francisco",
    units: 5
}, {
    location: "Miami",
    units: 2
}, {
    location: "San Francisco",
    units: 13
}, {
    location: "San Francisco",
    units: 2
}, {
    location: "Chicago",
    units: 16
}, {
    location: "Miami",
    units: 1
}];

var answer = deliveries.reduce(function(obj, val, index, all) {
    if (!obj[val.location]) {
        obj[val.location] = {
            times: 1,
            units: val.units
        }
    } else {

        obj[val.location].times += 1;
        obj[val.location].units += val.units;
    }

    return obj

}, {});

console.log(answer);

Answer №4

To achieve grouping, utilize Map objects.

var shipments = [{ location: "New York", units: 8 }, { location: "Los Angeles", units: 3 }, { location: "Dallas", units: 6 }, { location: "Los Angeles", units: 10 }, { location: "Chicago", units: 4 }, { location: "Dallas", units: 9 }];

var groupedResults = [];
shipments.reduce(
(locations, shipment) => locations.set(shipment.location, [...(locations.get(shipment.location) || []), shipment]), new Map
).forEach((shipments, city) => {
var summary = {};
summary[city] = shipments.length;
summary.units = shipments.reduce((totalUnits, currentShipment) => totalUnits + currentShipment.units, 0);
groupedResults.push(summary);
})
console.log(groupedResults);

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

Encountering a `Syntax Error` in a Jade view

I am attempting to create a basic chat application using the simple jade view engine with express. Upon running my app, I encountered a syntax error in the following view code, even though it seems quite straightforward. extends layout block scrip ...

What is the reason behind Object.hasOwn(x,y) being different from Reflect.ownKeys(x).includes(y) when x represents a CSSStyleDeclaration object and y is a hyphenated property such as 'z-index'?

Both of these conditions are true: 'z-index' in getComputedStyle(document.body) // true Reflect.has(getComputedStyle(document.body), 'z-index') // true Additionally, the following statements also evaluate to true, indicating that &apo ...

Function modification led to Sinon test failure

I am currently facing an issue with my test: describe('createNote', () => { beforeEach(() => { res = { json: sinon.spy(), sendStatus: sinon.spy(), }; }); afterEach(() => { noteService.createUserNote.restor ...

Create a list using ReactJS

I've been working on rendering a dynamic list in JSX, but I'm facing issues displaying the items. Below is my code snippet where I attempted to use useState const [orderList, setOrderList] = useState([]) and setOrderList(prev => [...prev, chil ...

Sending information with JSON using POST request through AJAX with PHP

Hello everyone! I have encountered a problem with my JavaScript/jQuery code and the way PHP is handling JSON input as an array. In my rate.php file, I am using print_r($_POST) to display the data, but it seems like PHP is not recognizing the JSON input cor ...

Angular retrieving a document collection from Firebase based on a specific field

I am trying to retrieve collection data based on the UserId field. retrieveData(){ const data$ = this.firestore.collection(this.trackerCollection,ref=> ref.where('UserId','==',"WrKDk0XSNjU20FI0EVRvADzvNHz1")).snapshotCha ...

Display the HTML content once the work with AJAX and jQuery has been successfully finished

Below are the codes that I have created to illustrate my question. It's not a complete set of code, just enough to explain my query. The process goes like this: HTML loads -> calls ajax -> gets JSON response -> appends table row with the JSO ...

uncertain outcome conditions prediction

While editing some code for a jQuery weather application, I encountered an issue where adding response fields did not clear all fields, resulting in undefined conditions. For example: Max. temp: 42C / 108F Min. temp: 27C / 80F wind: undefined $(function( ...

Save information to chrome's storage system

I have the need to save favorite and deleted IDs in my database. I created two functions for this purpose: function ADD_BLOCKED(id) { chrome.storage.local.get("blocked", function (data) { if (data.blocked == null) data.blocked = [] ...

Pattern matching for a string with numerous repetitions using Regular Expressions

There's a [tree] and a cat and a [dog] and a [car] too. I am looking to find the words inside each set of square brackets. The resulting array will be tree, dog, car My attempt at using match(/\[(.*)\]/g) didn't work as expected. It ...

Learn how to successfully carry on with event.preventdefault in JavaScript

Is there a way to create a modal that prompts the user to confirm if they want to leave the page without committing changes? These changes are not made within a <form> element, but rather on a specific object. I've attempted to use both $route ...

VARIABLE_NAME isn't functioning properly on the window

The code window.VARIABLE_NAME is not functioning properly and is causing the following error. Can you please provide assistance? Uncaught SyntaxError: Unexpected token. This is the code I have written: var window.testing ...

PHP is unable to retrieve the form that is included on the page

Utilizing the same HTML code in multiple locations, I decided to streamline by placing it in a .php file and including it as needed. One instance involves incorporating this code within a form. This particular form contains one element, with the inclusion ...

In the ajax call, an empty JSON array object is sent as the data

Utilizing JSON data as a parameter for an ajax call: var startDate = dateFormatForSave($("#start_date").val().trim()); var arrayOfStudentsInfo = []; var table = $("#selected_students"); table.find('tr').each(function(i, el) { var rowId = $( ...

Issues with Ionic's collection repeat functionality

I am currently iterating through an array of objects in my template and displaying them as cards using *ngfor. I want to switch to using collection repeat instead for better performance. Here is the code snippet: import { Component } from '@angular/ ...

Show parent menu when child menu is clicked

I'm dealing with a menu that has sub-child menus, and the issue I'm encountering is that whenever I choose a child menu after the page loads, the menu collapses. My goal is to have the parent menu open and expanded instead. This is the HTML Code ...

Encountering an error in Laravel 5.1 and Vue.js - Error code 21678: Uncaught TypeError: Unable to retrieve 'data' property from null

Recently, while working on my Laravel and Vue.js application, I encountered an issue. Everything was running smoothly until I added another component following the same procedures as before. Suddenly, the data stopped displaying in the table, and I started ...

What steps should be taken once the idToken in Firebase has expired?

My code is utilizing the onAuthStateChanged function: this.unregisterAuthObserver = firebase.auth().onAuthStateChanged(user => { if (user) { user.getIdToken(true).then((idToken) => { console.log(user) ... }); } After the idT ...

Combining the keys of two objects in JSON

console.log(a) ; // output in console window= 1 console.log(b);// output in console window= 2 var c = {a : b};// Is there a better way to do this? var d = JSON.stringify(c); d = encodeURIComponent(d); I want the final value of d to be {1:2}. ...

Which queue in Node does the callback from I/O operations returning promises get added to - the I/O queue or the microtask queue?

I'm currently delving into the intricacies of how Node's event loop operates. From my studies, I have discovered that the promise queue is given precedence over the timer queue, which in turn trumps the I/O queue. async function asyncFunc() { ...