What is the best way to tally jsonObject instances within the same array based on their id or value

I have a jsonDataArray that contains two nested arrays with objects. My goal is to calculate the number of "duty" parentIds based on the teams' "value" as they have a one-to-one match. For instance, Team A with a value of 500 will have duties such as Meetings and Lunch, while Team B will have duties like Time Cards, Parking, and Breakfast.

{
"jsonDataArray":[
  {
     "teams":[
     
        {
           "text":"Team A",
           "id":1,
           "value":500,
           "parentId":333
        },
        {
           "text":"Team B",
           "id":2,
           "value":600,
           "parentId":444
        }
        
     ],
     "duty":[
     
        {
           "text":"Meetings",
           "id":11,
           "value":100,
           "parentId":500
        },
        {
           "text":"Lunch",
           "id":12,
           "value":101,
           "parentId":500
        },
        {
           "text":"Time Cards",
           "id":13,
           "value":102,
           "parentId":600
        },
        
        {
           "text":"Parking",
           "id":14,
           "value":103,
           "parentId":600
        
        },
         {
           "text":"Breakfast",
           "id":15,
           "value":104,
           "parentId":600
        }
     ]
  
  }
 ]
}

I successfully retrieved the above JSON data using Vue (Axios). Below is my method.
I managed to count using reduce, but it only accounted for the first object in the array (teams) without any reference to duty. Is there a way to calculate by matching values and parentIds since they are in the same array...jsonDataArray.teams.value == jsonDataArray.duty.parentId ?

newJsonData() {
  var dutyCount = this.jsonDataArray.flatMap((item) => item.teams);

  let countValuesByKey = (arr, key) =>
    arr.reduce((r, c) => {
      r[c[key]] = (r[c[key]] || 0) + 1;
      return r;
    }, {});

  //returns numbers only 
  let countValue = (arr, key, value) =>
    arr.filter((x) => x[key] === value).length;

  console.debug("dutyCount", countValuesByKey(dutyCount, "text"));

  return dutyCount;
},

Expected Output:

{
  "Team A": 2,
  "Team B": 3
}

Answer №1

Your attempt is on the right track - there are multiple ways to achieve this, but in my opinion, sticking with the reduce() method is the simplest.

In the code below, I utilize reduce() twice: first to create an object mapping of team IDs to their names, and then to count the instances of each team's ID in the duty array:

const jsonResponse = {
  "jsonArray": [{
    "teams": [

      {
        "text": "Team A",
        "id": 1,
        "value": 500,
        "parentId": 333
      },
      {
        "text": "Team B",
        "id": 2,
        "value": 600,
        "parentId": 444
      }

    ],
    "duty": [

      {
        "text": "Meetings",
        "id": 11,
        "value": 100,
        "parentId": 500
      },
      {
        "text": "Lunch",
        "id": 12,
        "value": 101,
        "parentId": 500
      },
      {
        "text": "Time Cards",
        "id": 13,
        "value": 102,
        "parentId": 600
      },

      {
        "text": "Parking",
        "id": 14,
        "value": 103,
        "parentId": 600

      },
      {
        "text": "Breakfast",
        "id": 15,
        "value": 104,
        "parentId": 600
      }
    ]

  }]
};

function processJsonResponse(jsonResponse) {
  return jsonResponse['jsonArray'].map(cv => {
    var teams = cv['teams'].reduce((acc, team) => {
      acc[team['value']] = team['text'];
      return acc;
    }, {});
    return cv['duty'].reduce((acc, duty) => {
      acc[teams[duty['parentId']]] = acc[teams[duty['parentId']]] ? acc[teams[duty['parentId']]] + 1 : 1;
      return acc;
    }, {});
  });
};

console.log(processJsonResponse(jsonResponse));

This code can handle future scenarios where

jsonResponse['jsonArray'].length > 1
by using map() on jsonResponse['jsonArray']. To precisely match the expected output you've mentioned, simply add [0] to your call to processJsonResponse(), like this:
processJsonResponse(jsonResponse)[0]
.

Answer №2

To resolve the issue, utilize Array.reduce with appropriate indexing for both arrays.

Refer to the example below for a working solution:

const response = {
  jsonArray: [
    {
      teams: [
        { text: "Team A", id: 1, value: 500, parentId: 333 },
        { text: "Team B", id: 2, value: 600, parentId: 444 },
      ],
      duty: [
        { text: "Meetings", id: 11, value: 100, parentId: 500 },
        { text: "Lunch", id: 12, value: 101, parentId: 500 },
        { text: "Time Cards", id: 13, value: 102, parentId: 600 },
        { text: "Parking", id: 14, value: 103, parentId: 600 },
        { text: "Breakfast", id: 15, value: 104, parentId: 600 },
      ],
    },
  ],
};
const result = response.jsonArray[0].duty.reduce((acc, curr) => {
  const teamName = response.jsonArray[0].teams.find(
    (team) => team.value === curr.parentId
  );
  if (teamName && teamName.text) {
    acc[teamName.text] = acc[teamName.text] ? ++acc[teamName.text] : 1;
  }
  return acc;
}, {});
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

Tips for triggering functions when a user closes the browser or tab in Angular 9

I've exhausted all my research efforts in trying to find a solution that actually works. The problem I am facing is getting two methods from two different services to run when the browser or tab is closed. I attempted using the fetch API, which worke ...

Running a JavaScript test using the Mocha framework with an 'import' statement for a JS file

I am familiar with the module.export and require method: Requiring external js file for mocha testing While it is useful when dealing with modules, I find it inconvenient as I now need to test code in a specific file. For example, I have code in a file: ...

Loading a specific CSS file along with an HTML document

Creating a responsive website, I'm looking to incorporate a feature that allows for switching between a mobile version and a standard desktop version similar to what Wikipedia does. To achieve this, I would need to reload the current HTML file but en ...

Using Vue to dynamically wrap a component with a tag

Have you ever wondered how the v-if directive in Vue.js can hide an entire component along with its content based on a condition? I am curious to know: Is it possible to only hide the surrounding tag or component without removing its contents? ...

When dealing with dynamic components, vue-meta fails to consistently show the title, content, or schema upon page refresh or when clicking on an

After navigating to my dynamic components via the navigation bar, I noticed that the Vue-meta title, content, and schema are displayed correctly. However, upon refreshing the page or clicking on an external link, I encountered the issue of receiving a valu ...

"Unexpected discrepancy: Bootstrap Glyphicon fails to appear on webpage, however, is visible

I am having some trouble getting the glyphicon to display properly in my side nav. The arrow head should rotate down, which is a pretty standard feature. Here is the link to the page: The glyphicon should be visible on the "Nicky's Folders" top leve ...

Steps for adding an HTML string to a div element using Ajax

I am facing some major challenges with Ajax, especially when it comes to appending HTML code to a div. I am attempting to append this HTML string to <div id="content-loader"></div> PHP function getLogo(){ $logo = '<div class="bg- ...

calculating the duration between successive PHP form submissions

I am trying to calculate the duration between when a user submits a PHP form and when they submit it again. The form reloads on the same page, essentially refreshing it. Additionally, the user may enter the same data again. I want the timer to start runnin ...

Executing a cloud function in Firebase from an Angular-Ionic application by making an HTTP request

I am a newcomer to GCP and app development, so please bear with me if this question seems mundane. Currently, I have an angular-ionic app that is connected to Firebase allowing me to interact with the Firestore database. Now, my challenge is to invoke a ht ...

The second parameter of the Ajax request is not defined

Having an issue with my Ajax request in Vue.js where the second parameter is logging as undefined in the console. I've been trying to fix this problem but haven't found a solution yet. This is the code snippet for $.ajax(): //$.ajax() to add ag ...

My locale NUXT JavaScript files are being blocked by Content Security Policy

I've been working on implementing CSP headers for my website to ensure data is loaded from trusted sources. However, I'm facing an issue where CSP is blocking my local JS files. Here's a snippet from my nuxt.config.js: const self = 'lo ...

Changing synchronous functions to asynchronous

Attempting to transform synchronous calls into asynchronous ones using when...done. Despite being new at this, after extensive reading on the topic for the past two days, my code should work as intended. However, while it does function, it doesn't exe ...

The WYSIWYG niceEdit editor is incompatible with textareas generated through ajax-php calls, causing it to malfunction

My AJAX-generated textarea is not converting into a WYSIWYG Editor once loaded. The normal textarea works fine, but I need assistance in solving this issue. <!DOCTYPE html> <html> <head> ........ $.ajax({ type: "POST", ...

The ".splice()" method continuously removes the final element from an array

I have implemented a function on my form that allows me to add multiple file inputs for various images by clicking a button. Although this functionality is working correctly, I am facing an issue while trying to delete an input field using .splice. Instead ...

The express gateway is unable to transfer multipart/formdata

I've implemented express gateway as my main service gateway. One of the services I have needs to update an image, and when I try to handle files independently using multer it works fine. However, once this service is routed through express gateway, th ...

I am encountering an issue where the POST data is not being successfully sent using XMLHttpRequest unless I include

I have a unique website where users can input a cost code, which is then submitted and POSTed to a page called 'process-cost-code.php'. This page performs basic validation checks and saves the information to a database if everything is correct. T ...

Using JSON.stringify to format data and making an asynchronous $http request

I am working with a JavaScript string that looks like this: user_fav = "21,16"; I need to process this string through a function so that it becomes a JSON array with an id key, like this: {"id":21},{"id":16} This JSON array is then used in an $http req ...

Tips for serving a minified JavaScript file located in the dist directory on GitHub Pages

I recently followed a tutorial on creating an app using VueJS cli and now I want to deploy it on gh-pages. After generating the dist folder with the yarn generate command, I referred to a deployment guide to publish the app. However, when I visit the dep ...

Angular UI-Grid encountering difficulties in rendering secure HTML content

I'm having trouble displaying server-generated HTML in UI-Grid. Specifically, I want to show HTML content in my column header tooltips, but no matter what I try, the HTML is always encoded. Here's an example to illustrate the issue: var app = an ...

The self-made <Tab/> element is not functioning properly with the ".Mui-selected" class

I have customized a <Tab/> element and I want to change its selected color using Sandbox demo code export const Tab = styled(MuiTab)({ "&.Mui-selected": { color: "red" } }); However, I've noticed that: 1. Apply ...