0

I'm trying to group and add the similar elements in an array that I'm displaying in ng-repeat..

Plunker:Group Array Items

I tried to apply filter as:

<div ng-repeat="shape in shapes|filter:groupFilter">
  {{shape.name}}- {{shape.value}}
</div>

$scope.groupFilter=function(item)=>{
return item.name===item.name;
}

where I'm not able to access the whole elements at a time so that I can compare the values and add them up.. The end result that I'm expecting is like this...

Circle- 17 Rectangle- 13

forgottofly
  • 2,729
  • 11
  • 51
  • 93

2 Answers2

1

edit

Updated plunkr - http://jsfiddle.net/2s9ogyh8/1/

After reading the question again I realized that you were trying to group not only visually but you also wanted to aggregate values. If you were simply trying to group existing values, then you'd use my original answer.

Since you're aggregating the totals, I'd recommend doing so before the UI renders it, otherwise you encounter the $digest loop issue from @toskv's answer. His aggregating logic is pretty much the same though.

end edit


Here is a related post on this topic - orderBy multiple fields in Angular

Take a look at the built-in orderBy filter - https://docs.angularjs.org/api/ng/filter/orderBy

If you're looking for something more than just ordering by the name/type of shpae then you most likely won't be able to do this via a declarative object matcher but you can pass your groupFilter function back to it.

Updated plunker - http://jsfiddle.net/d13zmk3y/2/

Community
  • 1
  • 1
jusopi
  • 6,791
  • 2
  • 33
  • 44
  • Can I add the values of similar shape ? – forgottofly Jan 04 '16 at 17:04
  • I'm not sure I understand the question. Are you seeking show a totals by group/type/name type thing? – jusopi Jan 04 '16 at 18:05
  • nm, I understand now. No, this will simply order/group them based on the criteria set in the filter expression. In order to add these you'd need to do some data handling first before passing the data set to the ng-repeat. – jusopi Jan 04 '16 at 18:08
  • @jusopi that sounds like the best way to do it – toskv Jan 04 '16 at 18:26
  • @jusopi I wanted the solution as a filter..Can you pls suggest any method to do this only with a single filter in ng-repeat – forgottofly Jan 04 '16 at 18:57
  • I don't advise it. Filters work on existing values and data sets. Anytime you try to return a new data set, you trigger a $digest loop, which triggers the filtering, rinse & repeat. That's why you get the infinite loop error. You might be able to write a filter that hides certain values from the array and uses a scratch key to write the totals for the group, but then you're writing a *stateful* filter, which again is not recommended. Is there a reason you want to do this explicitly via a filter? – jusopi Jan 04 '16 at 19:04
0

A simple way to do it would be to make filter that uses reduce to group everything.

app.filter('group', function() {
  return function(items) {
    return items.reduce(function(aux, current) {
      if (aux[current.name]) {
        aux[current.name].count += parseInt(current.value, 10);
      } else {
        aux[current.name] = {
          name: current.name,
          count: parseInt(current.value, 10)
        };
      }
      return aux;
    }, {});
  };
});

You can see a fully working example here.

toskv
  • 30,680
  • 7
  • 72
  • 74