Calculating the mean value of a multidimensional array that has been sorted in JavaScript

Check out the structure of my JSON File below.

{
    "questions": ["Question1", "Question2"],
    "orgs": ["Org1", "Org2", "Org3"],
    "dates": ["Q1", "Q2", "Q3"],
    "values": [
        [
            [5, 88, 18],
            [50, 83, 10],
            [29, 78, 80]

        ],
        [
            [46, 51, 61],
            [95, 21, 15],
            [49, 86, 43]
        ]
    ]
}

I am attempting to extract a single array of values by looping through each question, indexed using an "orgs" value and then adding each retrieved value while dividing it by data.dates.length.

Below is the code I have;

d3.json("data.json", function(error, data) {

  var array = new Array()
  var orgS = "Org2"
  var org = data.orgs.indexOf(orgS);

  for (var question = 0; question < data.questions.length; question++) {
    array.push(
      data.values[question][org]
    )

    console.log(array)
  }

  // add array together
  array.reduce(function(a, b) {
    return a + b;
  })

  // calculate average
  var avg = array / data.dates.length;
})

Here is a plnk;

http://plnkr.co/edit/wMv8GmkD1ynjo9WZVlMb?p=preview

The issue I believe lies in how I am retrieving the values initially? Currently, even though the correct values are being displayed in the console log, they are showing up twice and both times inside nested arrays. Not sure how to fix this problem?

Just as a guide;

[question1][org1] corresponds to the values [5, 88, 18].

Any helpful advice would be much appreciated!

Thank you!

Answer №1

After taking into account your specific request to compute individual averages for each question, I have revised my response accordingly. It is advisable to carry out all the necessary calculations within the for loop as it iterates through the questions. Subsequently, you can save these averages in an array.

d3.json("data.json", function(error, data) {

  var calculatedAverages = new Array()
  var organizationSearched = "Org2"
  var orgIndex = data.orgs.indexOf(organizationSearched);

  var questionValues, totalSum;

  for (var i = 0; i < data.questions.length; i++) {
    // attain the values pertaining to the question/organization
    questionValues = data.values[i][orgIndex];

    // ascertain the total sum
    totalSum = questionValues.reduce(function(a, b) {
      return a + b;
    });

    // determine the average
    calculatedAverages.push(totalSum / questionValues.length);
  }

  console.log(calculatedAverages);

});

Answer №2

To achieve the desired outcome, utilize the .reduce() method within a for loop and then push the result into an array. This approach will provide you with an array containing the expected results.

array.push(data.values[question][org].reduce(function(a, b) {
  return a + b
}, 0) / data.dates.length)

[
  47.666666666666664,
  43.666666666666664
]

The current issue lies in attempting to perform addition on the arrays themselves within the .reduce() callback, rather than reducing the values of each individual array to their sum first, followed by calculating the average.

Demo: (Expand for full function)

var data = {
  "questions": ["Question1", "Question2"],
  "orgs": ["Org1", "Org2", "Org3"],
  "dates": ["Q1", "Q2", "Q3"],
  "values": [
    [
      [5, 88, 18],
      [50, 83, 10],
      [29, 78, 80]

    ],
    [
      [46, 51, 61],
      [95, 21, 15],
      [49, 86, 43]
    ]
  ]
}

x(data)

// Your callback function.
function x(data) {
  var array = new Array()
  var orgS = "Org2"
  var org = data.orgs.indexOf(orgS);

  for (var question = 0; question < data.questions.length; question++) {
    array.push(data.values[question][org].reduce(function(a, b) {
      return a + b
    }, 0) / data.dates.length)
  }

  console.log(array)
}


Another alternative to using a for loop is replacing it with the .map() method.

var array = data.questions.map(function(_, question) {
  return data.values[question][org].reduce(function(a, b) {
    return a + b
  }, 0) / data.dates.length
})

Demo: (Expand for full function)

var data = {
  "questions": ["Question1", "Question2"],
  "orgs": ["Org1", "Org2", "Org3"],
  "dates": ["Q1", "Q2", "Q3"],
  "values": [
    [
      [5, 88, 18],
      [50, 83, 10],
      [29, 78, 80]

    ],
    [
      [46, 51, 61],
      [95, 21, 15],
      [49, 86, 43]
    ]
  ]
}

x(data)

// Your callback function.
function x(data) {
  var orgS = "Org2"
  var org = data.orgs.indexOf(orgS);

  var array = data.questions.map(function(_, question) {
    return data.values[question][org].reduce(function(a, b) {
      return a + b
    }, 0) / data.dates.length
  })

  console.log(array)
}

Answer №3

To keep track of the total sum, utilize the result from the reduce function.

// Adding up all elements in array
// Storing the sum in a variable called 'sum'
var sum = array.reduce(function(a, b) {
    return a + b;
}, 0); // Initializing with 0 as starting value

When calculating the average, remember that instead of the length of data.dates, you need the length of the array since it holds all the values.

// Calculating the average
var avg = sum / array.length;

Merging all values together might look like this:

var data = { "questions": ["Question1", "Question2"], "orgs": ["Org1", "Org2", "Org3"], "dates": ["Q1", "Q2", "Q3"], "values": [[[5, 88, 18], [50, 83, 10], [29, 78, 80]], [[46, 51, 61], [95, 21, 15], [49, 86, 43]]] },
    sum = [];

data.values.forEach(function (a, i) {
    sum[i] = sum[i] || [];
    a.forEach(function (b) {
        b.forEach(function (c, j) {
            sum[i][j] = sum[i][j] || 0;
            sum[i][j] += c;
        });
    });
});

data.avg = sum.map(function (a, i) {
    return a.map(function (b) {
        return b / data.values[i].length;
    });
});

console.log(sum);
console.log(data);

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

What is the best way to apply custom styles in reactJs to toggle the visibility of Google Maps?

There are three radio buttons that correspond to school, restaurant, and store. Clicking on each button should display nearby locations of the selected type. Displaying Google Map and nearby places individually works fine without any issues. class Propert ...

Changing the color of a div while implementing a show and hide effect in JavaScript

I have designed a checkout system with three distinct parts - shipping information, billing information, and order confirmation. These sections are all on the same page, allowing for a seamless flow during the checkout process. Once a customer completes t ...

Using jQuery AJAX to Redirect to a 404 Page in Case the Load Method Encounters Failure

My website utilizes AJAX to load all pages using the jQuery load method. I modified this tutorial to work with Wordpress. The issue I am facing now is that when the load method encounters an error (such as a 404 due to a broken link), the AJAX transition ...

retrieving information via AJAX call using jQuery

I've been tasked with customizing a book website, and I'm trying to integrate reviews from the Goodreads API. However, my Ajax request isn't returning any data. Here is the code snippet: $.ajax({ 'type': 'GET', & ...

Browserify pulls in entire module even if only specific parts are utilized, such as react-addons

I am currently using Browserify to bundle my server-side react.js code for the client. There is a concern that utilizing a module from an npm package may result in the entire package being bundled by Browserify. Question: Will require('react-addons& ...

Unusual compilation issue encountered in Vue when trying to use a template for a slot

I encountered a strange issue where my Vue compiler was refusing to render the default named slot of a child component. Error: Codegen node is missing for element/if/for node. Apply appropriate transforms first. Even my VSCode highlighted this problem a ...

Efficient methods to reach the desired result using Selenium WebDriver promises

After working on a piece of code that utilizes Selenium WebDriver to retrieve the text of an element, I am wondering if there is a more concise way to accomplish this task? async function getText(driver, locator) { return await (await driver.findEleme ...

Continuously receiving unhandled promise rejection errors despite implementing a try-catch block

Every time I run my code, I encounter the following issue: An UnhandledPromiseRejectionWarning is being thrown, indicating that a promise rejection was not properly handled. This can happen if you throw an error inside an async function without a catch bl ...

What is the best way to input individual students' CA and exam scores into distinct fields and then calculate their total scores in a separate text field?

As a beginner in jQuery, I am looking for guidance on creating a script that calculates the Total score, Grade, Remark, and Position based on the user input of CAT score and EXAM score. The result should be displayed dynamically once both scores are entere ...

Cors policy error encountered in Node.js application and React application

I have developed an application using Node.js and React. I am currently hosting the server side on node.kutiza.com and the client side on finanu.kutiza.com through Namecheap. However, when I try to make a request to node.kutiza.com, I encounter an error me ...

What could be causing the state to continuously appear as null in my redux application?

Currently, I am in the process of developing a basic contacts application to gain expertise in React and Redux. The main focus right now is on implementing the feature to add a new contact. However, I have encountered an issue where the state being passed ...

My objective is to upload a video file and store it on the server using multer

My goal is to effectively receive and save a video file in the uploads folder with the proper extensions using node, express, and multer. Despite successfully passing the video to the server, it doesn't save as intended. Below is my backend code snipp ...

Implementing a JQuery modal with backend coding

I have encountered a problem in my ASP.NET code-behind where I am trying to incorporate a modal popup. Despite my efforts, I have not been able to successfully implement it. Do you have any suggestions on how I should proceed with this process? <scrip ...

Tips for utilizing Selenium Webdriver to input text into a webpage textbox using onblur, onfocus, and onkeydown attributes

I'm looking to streamline the process of inputting a value into a text box on a webpage, similar to automating my timesheet. The HTML code for the text box is shown below. <input type="text" class="" onblur="return setValue(this);" title="Time"; ...

Disable hover effects in CSS with JavaScript

I am looking for a way to deactivate CSS hover functionality using JavaScript. Within a form, there is a button that sends data to the database server. By utilizing OnClientClick() of an ASP.NET Button control, my goal is to modify the text of the element ...

Effortlessly retrieving the id attribute from an HTML tag using jQuery

Currently, I am encountering an issue with a code snippet that is designed to extract the value from an HTML tag. While it successfully retrieves a single word like 'desk', it fails when attempting to do so for an ID consisting of two or more wor ...

Struggling to make even the most basic example work with TypeScript and npm modules

After stumbling upon this repository that made using npm modules within a Typescript program look easy, I decided to give it a try by forking it and making some changes. My goal was to add another package to get a better understanding of the process. So, I ...

You cannot add properties to an object within an async function

I am attempting to include a fileUrl property in the order object within an async function, but I am unable to make it work properly. My expectation is for the order object to contain a fileUrl property once added, but unfortunately, it does not seem to b ...

MUI: reveal multiple selection when hovering & prevent dropdown from moving around

Utilizing material ui, I am facing two issues with a multiple select component that I cannot seem to resolve: While selecting an item, the dropdown moves around (I have already attempted solutions like MenuProps={{ variant: "menu", getContentAnc ...

How can I display the Bootstrap 5.3.0 Collapsible button on this basic website?

I've been struggling to implement a Bootstrap Collapsible on my web page using Bootstrap version 5.3.0. I've tried different approaches but I can't seem to get it to work. All I need is a Collapsible that contains a few links, which should b ...