0

I have an angular app in this plunker

I have a text area which has some text in the format of (key,count) in them by default.

What i am trying to achieve is this(in the calc() function):

When the button is pressed the results of the summation should be displayed.

I was able to split the data from the textarea into different arrays but i am missing the logic to add when the names match.

EDIT: please notice a few updates in my plunker

New to angular and javascript!

Abhishek
  • 2,998
  • 9
  • 42
  • 93

3 Answers3

3

This should do it.

JS:-

$scope.calc = function() {
  $scope.users = {};

   $scope.values.split('\n').forEach(function(itm){
     var person = itm.split(','),
         name,
         key;

      if(! itm.trim() || !person.length) return;

      name = person[0].trim()
      key = name.toLowerCase();

      $scope.users[key] = $scope.users[key] || {name:name, count:0};
      $scope.users[key].count += +person[1] || 0;
    });
}

HTML:-

<div class="alert alert-success" role="alert">
 <ul>
  <li ng-repeat="(k,user) in users">The total for {{user.name}} is {{user.count}}</li>
 </ul>
</div>

Demo

Add shim for trim() for older browsers.

PSL
  • 123,204
  • 21
  • 253
  • 243
  • hi can i get some help here? http://stackoverflow.com/questions/25625546/angularjs-create-a-dynamic-header-dropdowns-using-json-data – Abhishek Sep 02 '14 at 14:49
0

Here's another way to do it. I can't speak to performance against PSL's method, but I think this reads a little easier to my not-very good at javascript eyes.

function groupByName(names) {
  inputArray = names.split('\n');
  outputArray = {};

  for (i = 0; i < inputArray.length; i++) {

      var keyValuePair = inputArray[i].split(',');
      var key = keyValuePair[0];
      var count = Number(keyValuePair[1]);

      // create element if it doesnt' exist
      if (!outputArray[key]) outputArray[key] = 0;

      // increment by value
      outputArray[key] += count;
  }

  return outputArray;
}

This will produce an object that looks like this:

{
  "John": 6,
  "Jane": 8
}

You can display the name of each property and it's value with ng-repeat:

<li ng-repeat="(key, value) in groupedNames">
  The total for {{key}} is {{value}}
</li>

It's not an overwhelmingly complex bit of javascript, depending on the number of name value pairs. So you can probably even get rid of the manual calc button and just put a $watch on values in order to automatically recalculate totals with every change.

$scope.$watch('values', function() {
  $scope.groupedNames = groupByName($scope.values);
});

Demo in Plunker

Community
  • 1
  • 1
KyleMit
  • 30,350
  • 66
  • 462
  • 664
-1

You can build a TotalArray with the actual name (key) of your input as key and the count as value with it. Iterate over the input pairs and check if there is already a key called the key of this iteration if so: add the count to its value, otherwise create a new one in the TotalArray.

Some pseudo code that might help you:

inputArray = text.split('\n')
outputArray = []
for(i = 0, i< length, i++) {
    name = inputArray[i].split(',')[0]
    count = inputArray[i].split(',')[1]
    if (outputArray[name] exists) {
        outputArray[name] += count
    } else {
        outputArray[name] = count
    }
}

Now outputArray contains [[name1] => total_count1, [name2] => total_count2,... ]

I hope this helps you.

mathijs
  • 71
  • 7