Creating an object and increasing the count in an array with every iteration in JavaScript loop

I'm currently working on creating an object using a forEach loop in JavaScript. The goal is to total up all the counts for each item in the array and store them based on their type.

My project involves using Firebase in an Ionic (Angular/TypeScript) app, where I retrieve an array of items from the database. Here's an example of what the array structure looks like:

[
    {
        id:'uniqueID',
        specs: {
            count:5,
            forSale:false,
            group:"qPELnTnwGJEtJexgP2qX",
            name:"Foxeer Cam 2",
            type:"camera"
        }
    },
    {
        id:'uniqueID',
        specs: {
            count:4,
            forSale:false,
            group:"qPELnTnwGJEtJexgP2qX",
            name:"Furibee 40a",
            type:"esc"
        }
    },
    ...
]

To achieve this, I am iterating through these items (result being the list of items):

let partArr = [];
let typeObj = {};
result.forEach(part => {

  //Adding parts to the list
  partArr.push({
    'id':part.id,
    'specs':part.data(),
  });

  //Creating a list based on types
  typeObj[part.data().type] = {
    'count': 0
  };

});

The next step is to increment the counts by adding each part's count to the last count based on their type. The typeObj should be structured like this:

{
    esc: {
        count:5
    },
    camera: {
        count:10
    }
}

When trying to update the count, I encountered a problem where it didn't recognize the count when initially creating the object. Any tips or advice would be greatly appreciated!

Answer №1

To achieve this task of transforming an array into a single object, you can utilize the Array#reduce method:

const items = [
  {
    id: 'uniqueID',
    specs: {
      count: 5,
      forSale: false,
      group: "qPELnTnwGJEtJexgP2qX",
      name: "Foxeer Cam 2",
      type: "camera"
    }
  },
  {
    id: 'uniqueID',
    specs: {
      count: 4,
      forSale: false,
      group: "qPELnTnwGJEtJexgP2qX",
      name: "Furibee 40a",
      type: "esc"
    }
  },
  {
    id: 'uniqueID',
    specs: {
      count: 4,
      forSale: false,
      group: "qPELnTnwGJEtJexgP2qX",
      name: "Runcam Cam 1",
      type: "camera"
    }
  },
  {
    id: 'uniqueID',
    specs: {
      count: 1,
      forSale: false,
      group: "qPELnTnwGJEtJexgP2qX",
      name: "Hobbywing 4 in 1",
      type: "esc"
    }
  }
];
const typeObject = items.reduce((object, { specs: { count, type } }) => {
  object[type] = object[type] || { count: 0 };
  object[type].count += count;
  return object;
}, {});
console.log(typeObject);

The essence of this code is to initialize object[type] as itself or with a new object { count: 0 } if it doesn't exist yet. It then increments the count property of object[type] by the specified count provided in the data.

If you have a method named data that returns an object containing the data (as indicated in your question), you can adapt it like this:

const typeObject = items.reduce((object, item) => {
  const { type, count } = item.data().specs;
  object[type] = object[type] || { count: 0 };
  object[type].count += count;
  return object;
}, {});
console.log(typeObject);

Answer №2

Using the reduce method to create the object with counts in one go and only calling .data() once during each iteration would make the process much simpler:

const results = [
  {
    data() { return { specs: {
    count:5,
    forSale:false,
    group:"qPELnTnwGJEtJexgP2qX",
    name:"Foxeer Cam 2",
    type:"camera"
  }}}},
  {
    data() { return { specs: {
    count:4,
    forSale:false,
    group:"qPELnTnwGJEtJexgP2qX",
    name:"Furibee 40a",
    type:"esc"
  }}}},
  {
    data() { return { specs: {
    count:4,
    forSale:false,
    group:"qPELnTnwGJEtJexgP2qX",
    name:"Runcam Cam 1",
    type:"camera"
  }}}},
  {
    data() { return { specs: {
    count:1,
    forSale:false,
    group:"qPELnTnwGJEtJexgP2qX",
    name:"Hobbywing 4 in 1",
    type:"esc"
  }}}}
];
const typeObj = results.reduce((a, item) => {
  const { count, type } = item.data().specs;
  if (!a[type]) a[type] = { count: 0 };
  a[type].count += count;
  return a;
}, {});
console.log(typeObj);

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

Using an imported type in a React/Typescript project

import { AiOutlineLogout } from 'react-icons/ai'; import { IconType } from 'react-icons'; How can I correctly use the 'IconType' that I imported? (alias) type IconType = (props: IconBaseProps) => JSX.Element I have su ...

Children of unrelated parents may have similar height levels

Is there a way to make two unrelated divs have the same height using jQuery? Most solutions I found are for children of the same parent, but in this case, I need to equalize the heights of Parent B's child to Parent A's child. The code snippet be ...

What's causing my variables to be returned as null in the alerts?

Why am I receiving null values when alerting my variables? I'm attempting to pass a string stored in a variable from an external JavaScript file back to the main page using alerts. Initially, I suspected that the JavaScript was not fetching data cor ...

Maintaining a reference list of HTML elements in a lengthy v-for loop can lead to performance issues

Task I am facing a challenge with a long list of elements in a v-for loop. My goal is to trigger the .focus() method on the next element when the user presses the "arrow-down" key. My Attempt <script setup> import { ref } from 'vue' const ...

Creating uniform line lengths with a ruler utilizing Fabric.js

I have a div that scrolls horizontally and contains a ruler div and a canvas where I draw horizontal lines of varying lengths. When drawing the lines, I want to ensure they are accurately measured against the ruler using JavaScript and CSS: var canvas = ...

Clickable link unresponsive on parallax-enhanced webpage

Currently, I am utilizing Zurb foundation's Manifesto theme for creating a parallax scrolling landing page. The anchor tag is essential for the scrolling effect on this page, causing a conflict when regular anchor links are included. Here is the HTML ...

Using npm-installed cesium for the web browser is a straightforward process that involves importing

Exciting news - Cesium is now available on npm! Once I've run npm install cesium in my project, all the codes are placed inside the node_modules folder. In the introductory hello world example of Cesium, it imports cesium similar to this: <script ...

Ways to alter the drop-down button of a select tag to resemble the inner-spin-button found in <input type="number">

Is there a way to change the drop down button in a Select tag to an Inner-spin-button? Here is an image of what I am trying to achieve: https://i.sstatic.net/yEv5G.png select::-webkit-inner-spin-button{ -webkit-appearance: number; appearance: number; } ...

Increase the value of an array element based on the input from a specified label

In my JavaScript code, I am trying to increment the value of items by adding a label input from the user. I have set up an input label and button to receive and store the user input values. In my array, I have five items with unique Id's. However, I a ...

"Enhancing user experience: Downloading content as a PDF file with ReactJS in a web

I need assistance with providing a downloadable link for invoices. I save all the invoices in an array and when a user clicks on a particular invoice, it should download in the browser while keeping track using an index number. However, I am encountering a ...

Struggling to manage texbox with Reactjs

Currently working in Reactjs with Nextjs and encountering a problem with the "text box". When I use the "value" attribute in the textbox, I am unable to input anything, but when I use the "defaultValue" attribute, I receive a validation message saying "Ple ...

How can I find the shortest matching string in a file using TCL?

In a file, there are lines of text that can appear in any order: 1. A/B/C/D/E 2. A/B/C/D 3. X/Y/Z 4. X/Y 5. R/S/T/Q 6. L/M/N/O/P 7. L/M I need the output to be: 1. A/B/C/D 2. X/Y 3. R/S/T/Q 4. L/M The goal is to extract the shortest matching string amo ...

Struggling to create an AngularJS directive

My attempt to create a directive seems to be failing as the directive function is not being triggered. index.html <div ng-repeat="que in questions.Cars"> <question-dir>print from direcetive</question-dir> &l ...

Script to pop up cancel alert box

There's a dilemma with this code - if you click CANCEL the first time the box pops up, it continues to run. I'm unsure of how to make it redirect to the underlying page when clicked on cancel for the first time. var numero= prompt ("Enter a nu ...

Saving Various .NET Arrays (Matlab)

I am trying to store .NET arrays in a matrix without the need to convert them to a different data type. If I already have A = NET.createArray('System.Int16', n); B = NET.createArray('System.Int16', n); Is there a way to directly store ...

I'm having trouble with my next.js code that is supposed to handle dynamic content and routing

Currently, I am following a YouTube tutorial to learn next.js and have encountered an issue right at the beginning. I am attempting to develop dynamic content and routing for my website using the code snippet below, but I am facing an error: import Link fr ...

The initial rendering of the NextJs 13 application is experiencing significant sluggishness when deployed on an EC2

After deploying my NextJS 13.4 app on an AWS EC2 instance with 2 GB of RAM, I noticed that the initial load time is quite slow, taking around 20 seconds to load for the first time. The development mode in NextJS builds and displays the result, which may co ...

Adjusting the rotation transform by deleting and reapplying canvas is causing the chart to not display data after redrawing

I am facing a challenge with my previous issue and I am exploring different solutions. One approach I am considering is to remove the canvas element completely and then re-add it, effectively resetting all rotations on the canvas. Although this method alm ...

Transforming a 2D array into an array of objects

Here is an example of an array: let heroes = [ ["1", "Tony Stark"], ["2", "Steve Rogers"], ["3", "Thor"], ["4", "Nick Fury"] ]; I am looking to transform this array into an object with the following structure: let avengers = [ {id:"1", name:"T ...

Interacting with backend APIs using Angular 2

Currently, I am working on an Ionic AWS application and have completed the front-end development phase. Here is what I have so far: Front-end repository: Ionic front-end List of Backend repositories: Example resources Example get Example post ...