3

Firstly, I have an array with object element like below:

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

secondly , I have a new object :

$scope.selectedIngredientResults = {};

Now I wanna achieve one function in javascript like this:

count each object element of array and put them into a new object and store each

count

$scope.selectedIngredientResults = [

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

];

here is array with object elements

[![here is new object result, this is what I want,

I was trying 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 ); 
        }
    }

}
5
  • How are you identifying two objects as being the same (is it actually the same object, or just the same properties)? Commented Sep 5, 2016 at 12:57
  • please add some data for counting. Commented Sep 5, 2016 at 13:02
  • @ Paddy each object has ingredient_id and using obj.hasOwnProperty to identify 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; } Commented Sep 5, 2016 at 13:06
  • I know it's not the answer, but for this kind of task lodash is great lodash.com Commented Sep 5, 2016 at 13:44
  • If this is an AngularJS question, please tag it as so, as it may add different considerations than with vanilla Javascript. Commented Sep 5, 2016 at 15:34

4 Answers 4

1

first you need to apply group by by your key. then extract the result from the grouping. here is a transform function what you would need.

function transform(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;
}
Sign up to request clarification or add additional context in comments.

5 Comments

i am trying to understand your code, but i still can not understand what's going on here items = items.reduce(function (memo, val) { var key = val['ingredient_id']; if (!memo[key]) { memo[key] = []; } memo[key].push(val); return memo; }, {});
it's applying group by operation. just console.log(items) when reducing is done, you'll know what is been done for more abount reduce see(developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…). :)
can u explain val['ingredient_id'] ?@Sufian Saory
val is the current object for the reducing iteration. val['ingredient_id'] is the value of the ingredient_id which is the key for our group by operation. please see(w3schools.com/jsref/jsref_reduce.asp) with example of reduce.
Thanks @Sufian Saory
0
function getIngredientResults (ingredients) {
  var source = [].slice.call(ingredients)
  var result = []

  while (source.length > 0) {
    // Move first item from source.
    var current = source.shift()

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

      return carry
    }, [])

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

    // Add data to result
    result.push({
      ingredient: current,
      count: duplicateIndexes.length + 1
    })
  }

  return result
}

2 Comments

sorry @Jon Koops it is my fault, i should tag it AngularJS, but still thank your help
This is just a function, you can use it with AngularJS. AngularJS is still JavaScript...
0

I guess this was already answered but here's how to do it in one reduce:

$scope.selectedIngredientResults = $scope.selectedIngredient.reduce(function (result, item) {
    var foundIndex = -1;
    var found = result.some(function (alreadyCounted, i) {
        if (alreadyCounted.object.ingredient_id === item.ingredient_id) {
            foundIndex = i;
            return true;
        }
        return false;
    });
    if (found && foundIndex !== -1) result[foundIndex].count += 1;
    else result.push({object: item, count: 1});
    return result;
}, []);

Comments

0

** I spend some time to learn these new methods above your guys answer and get some inspiration from these and worked it out by another way , Thank u so much guys **

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);
}

} });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.