简体   繁体   中英

Javascript count unique array occurrence

Following were an output from an array returned by following function:

$scope.variantOptions = $scope.variantLists.join(", ");

medium,small,medium,small,small

How can I sort the result, so it represent the output as:

medium x 2,small x 3

EDIT

addCount function:

$scope.addCount = function($index){

        $scope.counter = 1;

        if($scope.activity['variant'][$index]['count'] != undefined ){

            $scope.counter = parseInt($scope.activity['variant'][$index]["count"]) +1;

            $scope.variantLists.push($scope.activity['variant'][$index]['variant_dtl_name']);

        }


        $scope.activity['variant'][$index]["count"] =  $scope.counter;

        console.log(arraySimplify($scope.variantLists));


    };

Thanks!

pass your '$scope.variantLists' arry into this function it will give you the expected result.

     function arraySimplify(arr){
        arr.sort();
        var rslt = [], element =arr[0] ,count = 0 ;

        if(arr.length === 0) return; //exit for empty array

        for(var i = 0; i < arr.length; i++){
            //count the occurences
            if(element !== arr[i]){
                rslt.push(element + ' x ' + count);
                count =1;
                element = arr[i];
            }
            else{
                count++;
            }
        }
        rslt.push(element + ' x ' + count);
        return rslt.join(', ');
    }

Your code is working:

for (var i = 0;i < $scope.variantLists.length;i++) {
    obj[arr[i]] = (obj[arr[i]] || 0) + 1; 
}

Gives you an object:

obj = {medium: 2, small: 3}

To see it without having to go into the console, you can just alert the object after the 'for' loop:

alert(obj);

To get the EXACT string you want:

var string = "";
for (var key in obj) {
   if (obj.hasOwnProperty(key)) {
       var count = validation_messages[key];
       string += key + " x " + count;
    }
}

Although it may look like an entry in Code Golf but this is one of the rare times when Array.reduce makes sense.

var r = a.sort().reduce(
                   function(A,i){
                     A.set(i, (!A.get(i))?1:A.get(i)+1);
                     return A;
                   },new Map());

Which makes basically what Jon Stevens proposed but in a more modern and highly illegible way. I used a Map because the order in a normal Object dictionary is not guaranteed in a forEach loop. Here r.forEach(function(v,k,m){console.log(k + ":" + v);}) gets printed in the order of insertion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM