exploring the similarities between arrays containing nested objects

Can you assist me, please? I need help comparing and calculating the percentage difference between values and returning an array. I have to compare arrays, access objects with names and values, and calculate the percentage. For instance, if the first item in the array is {name: 'Name 1', value: 1945}, and the second item is {name: 'Name 1', value: 699}, the percentage for 1945 will be 100 and for 699, it will be 36. I'm struggling with the nesting aspect.

//input data
const data = [
  {
    _id: "0090908",
    groups: [
      {
        _id: "24424",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 1945 },
          { name: "Name 2", value: 0 },
          { name: "Name 3", value: 39 },
        ],
      },
      {
        _id: "23030",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 67 },
          { name: "Name 5", value: 123 },
          { name: "Name 6", value: 13 },
        ],
      },
    ]
  },
  {
    _id: "00390395",
    groups: [
      {
        _id: "837583",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 699 },
          { name: "Name 2", value: 55},
          { name: "Name 3", value: 39 },
        ],
      },
      {
        _id: "8989305",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 998 },
          { name: "Name 5", value: 12 },
          { name: "Name 6", value: 485 },
        ],
      },
    ]
  }
];

//result data
const result = [
  {
    _id: "0090908",
    groups: [
      {
        _id: "24424",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 1945, percent: 100, best: true },
          { name: "Name 2", value: 0, percent: 0, best: false },
          { name: "Name 3", value: 39, percent: 100, best: true },
        ],
      },
      {
        _id: "23030",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 67, percent: 6, best: false },
          { name: "Name 5", value: 123, percent: 100, best: true },
          { name: "Name 6", value: 13, percent: 3, best: true },
        ],
      },
    ]
  },
  {
    _id: "00390395",
    groups: [
      {
        _id: "837583",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 699, percent: 36, best: false },
          { name: "Name 2", value: 55, percent: 100, best: true},
          { name: "Name 3", value: 39, percent: 100, best: true },
        ],
      },
      {
        _id: "8989305",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 998, percent: 100, best: true },
          { name: "Name 5", value: 12, percent: 9, best: false },
          { name: "Name 6", value: 485, percent: 100, best: true },
        ],
      },
    ]
  }
];

Answer №1

Initially, you must iterate through all elements to identify the highest values for each name. Subsequently, iterate again to assign the corresponding percentages.

var best = {}; // Collection of highest values

function checkLargest(data) {
  if (!data) return;
  if (Symbol.iterator in Object(data)) for (var el of data) checkLargest(el);
  if (data.name && data.value !== undefined)
    if (!best[data.name] || best[data.name] < data.value)
      best[data.name] = data.value;
  checkLargest(data.groups);
  checkLargest(data.items);
}

function placePercentages(data) {
  if (!data) return;
  if (Symbol.iterator in Object(data)) for (var el of data) placePercentages(el);
  if (data.name && data.value !== undefined) {
    var higher = best[data.name];
    data.percent = Math.round(data.value / higher * 100);
    data.best = (higher == data.value);
  }
  placePercentages(data.groups);
  placePercentages(data.items);
}

const d = [
  {
    _id: "0090908",
    groups: [
      {
        _id: "24424",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 1945 },
          { name: "Name 2", value: 0 },
          { name: "Name 3", value: 39 },
        ],
      },
      {
        _id: "23030",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 67 },
          { name: "Name 5", value: 123 },
          { name: "Name 6", value: 13 },
        ],
      },
    ]
  },
  {
    _id: "00390395",
    groups: [
      {
        _id: "837583",
        name: "Group 1",
        group_type: "group_1",
        items: [
          { name: "Name 1", value: 699 },
          { name: "Name 2", value: 55},
          { name: "Name 3", value: 39 },
        ],
      },
      {
        _id: "8989305",
        name: "Group 2",
        group_type: "group_2",
        items: [
          { name: "Name 4", value: 998 },
          { name: "Name 5", value: 12 },
          { name: "Name 6", value: 485 },
        ],
      },
    ]
  }
];

checkLargest(d);
placePercentages(d);
console.log(d);

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

retrieving information from a data attribute

When setting a data attribute for a user on a link, the code looks like this: <input type="button" class="btn" data-user={"user": "<%= @user.name %>"} value="Start" id="game"> Upon listening for the click event in the JavaScript function, co ...

Guide on retrieving a value from a function that invokes $.getJSON

function searchAndRetrieve(searchTerm) { var defaultResult = 1010; var resultValue = defaultResult; $.getJSON(remote, function(data) { if (data != null) { $.each(data.items, function(i, item) { ...

Error encountered in Intellij for Typescript interface: SyntaxError - Unexpected identifier

I am currently testing a basic interface with the following code: interface TestInterface { id: number; text: string; } const testInterfaceImplementation: TestInterface = { id: 1, text: 'sample text' }; console.log(testInterface ...

selecting a number at random from a defined array

I am looking to generate a series of lottery numbers like the following: my list could be between 1 - 100, or it might range from 1 - 200, or even 1 - 300 select 35 random numbers from the chosen list. choose another set of 25 numbers from the list. pic ...

Looking for a JavaScript function that can utilize AJAX to execute PHP code and display the PHP output on the webpage

I've been trying to use JavaScript to execute some PHP code and then display the results on the page. I came across a piece of code that achieves this using ajax and by placing the PHP code in an external file. However, the code I found seems to show ...

SmartCollection in Meteor generating unpredictable outcomes

When executing News.insert({name: 'Test'}) in the browser JS console, it caused {{count}} to increase from 0 to 1. Checking in mongo console using mrt mongo, db.news.find().count() also returns 1. However, after adding a record through the mongo ...

Accessing JS code from HTML is not possible in React

Attempting to create a list using React, I have utilized the module found here: https://github.com/pqx/react-ui-tree I am currently testing out the sample application provided in this link: https://github.com/pqx/react-ui-tree/blob/gh-pages/example/app.js ...

How to efficiently switch between classes in Ember Octane using Handlebars?

What is the best way to toggle between displaying a class on and off using Ember.js Octane? Should I use an @action or @tracked in this case? <img src="flower.jpg" alt="flower" class="display-on"> or <img src="flower.jpg" alt="flower" class=" ...

"Displaying the state value retrieved from a custom hook is not working as expected

Creating a custom hook, Custom.js: import React, {useState, useEffect} from 'react'; import Clarifai from 'clarifai'; const app = new Clarifai.App({ apiKey: 'XXXXXXXXXXXXXX' }) const CustomHook = () => { const [i ...

The function is not recognized in C# programming language

Whenever I try to trigger functions by clicking buttons, nothing seems to happen and an error message appears in the console. Uncaught ReferenceError: AddressInputSet is not defined at HTMLButtonElement.onclick I'm new to this and could use ...

Clicking the mouse within three.js

I'm facing an issue with my webpage that features a three.js (webgl) graphic created using a .dae file imported from Blender. My goal is to draw a square or mark wherever the mouse is clicked, but for some reason, the square appears in a different loc ...

Integrating Gesture Handling in Leaflet JS for two-finger scrolling enforcement

Have you ever noticed that when you're using a mobile device and scrolling down a webpage with a Google map, the map goes dark and prompts you to "Use two fingers to move the map"? https://i.stack.imgur.com/4HD1M.jpg I am interested in incorporating ...

Demonstrate the utilization of JQuery to unveil a secondary menu

I need assistance in implementing a sub-menu that automatically appears within 2 seconds after the page loads, instead of requiring user interaction. I am currently utilizing JQuery, which serves as the core framework for my website. It is crucial for this ...

What is the best way to display every comment and response using console.log()?

Currently, I am developing a commenting system where users can leave comments and reply to existing comments. In the MySQL database image Both images depict the same scenario. In my highlighted text in yellow, it should read comments[0] instead of comment ...

Dealing with AngularJS: Overcoming Lexer Errors When Passing Email Addresses for Regex Validation in Functions

Trying to pass an email address to an AngularJS function has been my recent challenge. Below is a snippet of the code I've been working on. <script> //For simplicity, descriptions for the module and service have been omitted this.sendEmail = f ...

Filtering substrings in an Angular data resource

DEFAULT_RECORDS = [{ id: 1, name: 'John Evans', number: '01928 356115' },{ id: 16, name: 'Murbinator', number: '053180 080000' }]; - retrieveEntries: function (name) { var foundRecords = {}; ...

What is the best method for transforming a stream into a file with AngularJS?

Currently, I have a server returning a file stream (StreamingOutput). My goal is to convert this file stream into an actual file using AngularJS, javascript, JQuery, or any other relevant libraries. I am looking to display the file in a <div> or ano ...

JavaScript error - Property value is not valid

When I use IE 6/7/8, I encounter a JavaScript error message. The problematic line of code reads as follows: document.getElementById('all').style.backgroundColor = color; The specific error reported in IE 6/7/8 is as follows: Invalid property ...

What is the best way to display the currently selected value in a Vue select drop down?

Is there a way to make the selected item in a custom component dropdown appear, similar to this Vue.js question? I have debug output within my single file component (SFC). <script> export default { props: ['modelValue', 'options&apos ...

Manipulating Arrays in JavaScript: Techniques for Extracting Values Buried in Nested Objects

I am working with an array of objects that contain multiple "Book" objects with dynamic keys. My goal is to filter the objects in the array to only include those that have at least one new "Book" object. For example: const arr = [ { id: '123&ap ...