简体   繁体   中英

Custom Sort based on String length

I am trying to sort this data.

My data looks like this:

var test =   [
            {label: '41_45', 
            value :14},
            {label: '46_50', 
            value :34},
            {label: '1', 
             value :44},
            {label: '10_15', 
            value :84}
            {label: '3', 
            value :44},
            {label: '6_10', 
            value :94},
            {label: '16_20', 
            value :74},
            {label: '21_25', 
            value :64},
            {label: '26_30', 
            value :44},
            {label: '31_35',
            {label: '4', 
            value :44},
            {label: '5', 
            value :24},
            {label: '36_40', 
            value :444},
            {label: '>50', 
            value :24},
            {label: '2', 
            value :44}
        ];

But I want to sort it based on label so that I can get results like this:

  var test =   [
            {label: '1', 
            value :44},
            {label: '2', 
            value :44},
            {label: '3', 
            value :44},
            {label: '4', 
            value :44},
            {label: '5', 
            value :24},
            {label: '6_10', 
            value :94},
            {label: '11_15', 
            value :84},
            {label: '16_20', 
            value :74},
            {label: '21_25', 
            value :64},
            {label: '26_30', 
            value :44},
            {label: '31_35', 
            value :4},
            {label: '36_40', 
            value :444},
            {label: '41_45', 
            value :14},
            {label: '46_50', 
            value :34},
            {label: '>50', 
            value :24}
        ];

Is there any library or function which I can leverage to achieve this?

While this could be done using the angular filters (as others have mentioned), it can also be done before the view logic, utilizing the JavaScript function array.sort() . sort() can accept an optional function compareFunction that can handle sorting the items:

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b, ie a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (eg Mozilla versions dating back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
  • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined. 1

To compare the label property of each item, which is a string, use parseInt() to parse an integer from the strings when comparing the items, like in the code below. Notice 10 is passed as the radix (2 nd argument) to ensure no strings get parsed as a hex/octal number by mistake.

var newArray = test.sort(function(item1, item2) {
    if (parseInt(item1.label,10) < parseInt(item2.label,10)) {
         return -1; //put item2 after item1
    } 
    return 1; //otherwise put item1 after item2
});

See a demonstration of this below (click Run code snippet to see the results). The conditional logic has been simplified using a ternary operator .

 var test = [{ label: '41_45', value: 14 }, { label: '46_50', value: 34 }, { label: '1', value: 44 }, { label: '10_15', value: 84 }, { label: '3', value: 44 }, { label: '6_10', value: 94 }, { label: '16_20', value: 74 }, { label: '21_25', value: 64 }, { label: '26_30', value: 44 }, { label: '31_35' }, { label: '4}', value: 44 }, { label: '5', value: 24 }, { label: '36_40', value: 444 }, { label: '>50', value: 24 }, { label: '2', value: 44 }]; var newArray = test.sort(function(item1, item2) { return (parseInt(item1.label,10) < parseInt(item2.label,10))?-1:1; }); console.log(newArray); 


1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

A good option is to use loadash sortby

var users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];

_.sortBy(users, [function(o) { return o.user; }]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]

_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]

If you want to do it in the view using angular , you can use orderby with the ng repeat filter,

Code:

 <div ng-repeat="item in test | orderBy:'label' ">
    <h1>{{item}}</h1>
  </div>

If you want to do it in controller, you can use $filter,

Code

$scope.filtered =  $filter('orderBy')($scope.test, 'label');

DEMO

 var app = angular.module('app', []); app.controller('loginController', ['$scope','$filter', function($scope,$filter) { $scope.test = [{ label: '41_45', value: 14 }, { label: '46_50', value: 34 }, { label: '1', value: 44 }, { label: '10_15', value: 84 }, { label: '3', value: 44 }, { label: '6_10', value: 94 }, { label: '16_20', value: 74 }, { label: '21_25', value: 64 }, { label: '26_30', value: 44 }, { label: '31_35' }, { label: '4}', value: 44 }, { label: '5', value: 24 }, { label: '36_40', value: 444 }, { label: '>50', value: 24 }, { label: '2', value: 44 }]; $scope.filtered = $filter('orderBy')($scope.test, 'label'); }]); 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body ng-app="app" ng-controller="loginController"> <div ng-repeat="item in filtered"> <h1>{{item}}</h1> </div> <script type=" text/javascript " src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js "></script> <script type="text/javascript " src="MainViewController.js "></script> </body> </html> 

Feasible Solution will is already suggested by @Sajeetharan . Angular provides you better control over this data which will be efficient as well as very easy to implement.

you can use filters from angular js to get the output in time.

 <table>
       <tr>
          <td>label</td>
          <td>value</td>
       </tr>
       <div ng-repeat="data in test | orderBy:'label' ">
          <tr>
             <td>data.label</td>
             <td>data.value</td>
          </tr>
       </div>
  <table> 

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