Learn the process of merging an array element into another object and keeping track of the total count

Initially, my array contains object elements as shown below:

$scope.selectedIngredient = [object1, object2, object3, object1, object2];

Next, I have a new object :

$scope.selectedIngredientResults = {};

Now, I want to create a JavaScript function that does the following:

Count each object element in the array and store them in a new object along with their counts.

$scope.selectedIngredientResults = [

    {"object" : object1, "count" : 2},
    {"object" : object2, "count" : 2},
    {"object" : object3, "count" : 1}

];

https://i.sstatic.net/N4miS.png

[![Here is the resulting new object that I want,

I attempted to achieve this by using

$scope.addIngredient = function(selectedElement) {

console.log('selectedElement', selectedElement);
$scope.selectedIngredient.push(selectedElement);
console.log('$scope.selectedIngredient' , $scope.selectedIngredient);
$scope.selectedIngredientResults = {};
var lengthofR = $scope.selectedIngredient.length;

for (var i = lengthofR - 1; i >= 0; i--) {
    var selected = $scope.selectedIngredient[i]['ingredient_id'];
    console.log('lengthofR', lengthofR);
    if(selected){
        if($scope.selectedIngredientResults.hasOwnProperty(selected)){

            $scope.selectedIngredientResults[$scope.selectedIngredient]++;
        }else {
      $scope.selectedIngredientResults[$scope.selectedIngredient] = 1;
        }
         console.log('$scope.selectedIngredientResults', $scope.selectedIngredientResults ); 
        }
    }

}

Answer №1

If you want to group your data by a specific key, the first step is to apply the group by function. After that, extract the result from the grouping. Below is a custom transform function that accomplishes this:

function transformData(items) {
    items = items.reduce(function (memo, val) {
        var key = val['ingredient_id'];
        if (!memo[key]) {
            memo[key] = [];
        }
        memo[key].push(val);

        return memo;
    }, {});

    var result = [];
    for (var k in items) {
        var groups = items[k];
        result.push({ 'object': groups[0], 'count': groups.length });
    }

    return result;
}

Answer №2

function findUniqueIngredients(ingredientsList) {
  var sourceArray = [].slice.call(ingredientsList);
  var uniqueResults = [];

  while (sourceArray.length > 0) {
    // Get the first item from the source.
    var currentItem = sourceArray.shift();

    // Find indexes of duplicate entries.
    var duplicateIndexes = sourceArray.reduce(function(carry, item, index) {
      if (item.ingredient_id === currentItem.ingredient_id) {
        carry.push(index);
      }

      return carry;
    }, []);

    // Remove duplicates from the source array.
    duplicateIndexes.forEach(function(index) {
      sourceArray.splice(index, 1);
    });

    // Add unique data to the result array.
    uniqueResults.push({
      ingredient: currentItem,
      count: duplicateIndexes.length + 1
    });
  }

  return uniqueResults;
}

Answer №3

Although this question may have been answered before, I'll provide a solution using a single reduce function:

$scope.updatedIngredientResults = $scope.selectedIngredient.reduce(function (newResult, currentItem) {
    var foundIndex = -1;
    var alreadyFound = newResult.some(function (previouslyCounted, index) {
        if (previouslyCounted.object.ingredient_id === currentItem.ingredient_id) {
            foundIndex = index;
            return true;
        }
        return false;
    });
    if (alreadyFound && foundIndex !== -1) newResult[foundIndex].count += 1;
    else newResult.push({object: currentItem, count: 1});
    return newResult;
}, []);

Answer №4

** After exploring new methods inspired by your answers, I managed to solve the problem in a different way. Thank you all for your help! **

myApp.controller('addIngredientCtrl', function($scope) {
$scope.selectedIngredient = [];

$scope.addIngredient = function(selectedElement) {
var elementIndex = $scope.selectedIngredient.indexOf(selectedElement);
if(elementIndex === -1) {
  selectedElement['customerCartQuantity'] = 1;
  $scope.selectedIngredient.push(selectedElement);
} else {
  $scope.changeIngredientQuantity($scope.selectedIngredient[elementIndex],   1);
 }
 }

$scope.changeIngredientQuantity = function(selectedElement, value) {
var elementIndex = $scope.selectedIngredient.indexOf(selectedElement);
$scope.selectedIngredient[elementIndex].customerCartQuantity += value; 
if($scope.selectedIngredient[elementIndex].customerCartQuantity == 0) {
  $scope.selectedIngredient.splice(elementIndex, 1);
}

} });

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

Callback issues in need of resolving

This problem seems like it should have a simple solution, but I think I've been staring at it for too long. Initially, I had this function inline, but now I want to extract it and use it in other parts of my application. However, I'm struggling ...

Issue with Cascading Dropdowns in jQuery

I am currently experiencing issues with a piece of code on my website (also accessible via this link). The code consists of 2 select fields that should display different data based on the selection made. However, I have identified 2 bugs within the code. ...

Is there a way to retrieve the name associated with a channel/server ID?

As I work on enhancing the console log for my discord bot, one of my objectives is to capture all the messages visible to the bot. Here's what I have done so far: client.on('message', message => { const User = client.users.cache.get(m ...

The behavior of having two submit buttons within the $document.ready(function) in Jquery

In my code, I have implemented the behavior of two buttons, button1 and button2, within a $(document).ready(function). Whenever either button is clicked, an alert() function should be triggered. However, it seems that only button2 is functioning properly w ...

Unusual activity observed in HTML5 contenteditable functionality

Within a list item, I have a span element. <ul> <li>text part 1 <span class="note">this is a note</span> text part 2 </li> <li>text part 3</li> </ul> When you double click on th ...

Issues Persist with Bootstrap Tree View - object passed but no output显示

After going through numerous discussions and solving several issues along the way, I have encountered a major problem where there is no output. As mentioned before, I am utilizing Bootstrap Tree View: To establish the hierarchical structure required for ...

Iterating through a two-dimensional array in Javascript

Hosting a gathering means serving pizza, but each guest has specific topping preferences. As more people RSVP, you'll need to anticipate the amount of pizza to order and which toppings to include. To simplify this task, you can develop a JavaScript pr ...

Is there a way to selectively include a filter in ng-repeat within a directive?

Utilizing an element directive across multiple views, the directive iterates through each 'resource' in a list of resources using ng-repeat="resource in resources". Different page controllers determine which resources are fetched from the API by ...

The message from the XHR Object appears to be undefined, yet it correctly displays the status

I am currently working on an ajax call that is expected to return a 400 http error code. The backend language being used is PHP. Here is my PHP code: header('Content-Type: text/html',true,400); echo $this->upload->display_errors('< ...

Issue with utilizing Vuejs variable in Google Maps Matrix API function

Having trouble accessing a Vue.js variable in a function using the Google Maps Matrix API. I am trying to use the Google Distance Matrix API to calculate the distance between two locations. I have declared a variable globally and changed it within a functi ...

Instructions on utilizing module.exports to export an async function

I am facing an issue with returning the result of an async function to the route I am calling. How can I resolve this successfully? My goal is to export a token from file token_generator.js and display it on route ('/') using Express. The functi ...

Shopping Directive Coverage Discrepancy

In my application, there is a shop item directive that includes a price attribute. When a user interacts with the directive, the total cost (a variable stored in the main controller) should be updated by the price of the item that was clicked. Unfortunate ...

Separating text for tooltips from the element itself

I'm looking to enhance my website by adding tooltip descriptions to elements based on their CSS classes. While tooltips are usually added using the element's title attribute, I have numerous elements with the same lengthy description and want to ...

Getting the value of a button using JavaScript

Is there a way to retrieve the value of a button when multiple buttons are generated dynamically? I have a JavaScript function that creates buttons in a list based on my search history, with each button labeled as a city name. However, after clicking on o ...

When the 'Show More' button is clicked, one Div will smoothly slide over another Div

I've been struggling for hours to find a way to make one DIV slide over another DIV below it instead of pushing it down. The setup is quite straightforward. I have a script that reveals more text when the 'Show More' button is clicked. Desp ...

Display or Conceal form based on radio button selection of affirmative or negative

I'm experimenting with using jQuery to display more or less of a form depending on the user's selection. If the user chooses 'Yes,' then additional form fields will be shown. I intend to implement this feature for various top-level ques ...

Is there a way to confirm that a list within my model contains at least one element?

In my code with Angular 1.6, I have a structure like this: <div class="house" ng-repeat="house in $ctrl.houses" ng-form="houseForm"> <div class="room" ng-repeat="room in house.rooms" ng-form="roomForm"> <div class="item" ng-repeat="it ...

Failure to start selection process on narrowed down list

The code snippet provided is functioning properly, with the exception of one issue: the UI's drop-down menu fails to initialize with the contents of the model. The initialization of the model is correct, and the cookies are being saved and loaded succ ...

Using Wordpress: Transferring a PHP Array to a JavaScript Function

Is there a way to incorporate a PHP Array, which I am fetching in the WP-Loop, into a separate javascript function that is stored in a different js file? This is how I am displaying my PHP Array (from Advanced Custom Fields) in the loop: $images = get_fi ...

Is it possible to instantiate a Backbone view by referencing its string name that is stored within a JavaScript object?

I am currently working on a visual builder that utilizes different views for each component. Each view is defined as shown below: $(function() { var parallaxView = new Backbone.view.extend({ .... }); var parallaxView = new Backbone.view.e ...