0

I have an array where each row looks like this:

array = [[ 'A2', 'A3', 'X' ], [ 'A1', 'Z', 'VZZ' ]]

The array has no keys. Currently I am accessing the values simply by the position of the value (ie. array[0], array[1] and so forth) and it works fine.

However I would like to order the rows, say by the first value.

How can I do this in angularJs ?

I tried things like ... | orderBy:$index but it does not work.

8 Answers8

4

Just vanilla Array.sort !

very basic exemple !

var arr = [[ 'A2', 'A3', 'X' ], [ 'A1', 'Z', 'VZZ' ] ,  [ 'A4', 'P', 'VZZ' ]  , [ 'A3', 'X', 'VZZ' ]];


console.dir( arr.sort(function(a , b){ return a[0] < b[0]} );
semirturgay
  • 4,151
  • 3
  • 30
  • 50
Anonymous0day
  • 3,012
  • 1
  • 14
  • 16
3

I dont know about using orderBy in this case but you can use a custom filter like this:

suppose your markup is like this:

<div ng-repeat="item in array">
</div>

Now, add a custom filter like this:

<div ng-repeat="item in array | customOrder">
</div>

Now define the filter like this:

app.filter('customOrder', function() {
    return function(collection) {
        //collection is your complete array
        //sort the collection
        collection.sort(function(a, b) {
            return a[0] - b[0]; //sort the collection using the first element of the array
        }) 

        //finally returned the sorted collection
        return collection;
    }
})
Tarun Dugar
  • 8,921
  • 8
  • 42
  • 79
2

You don't need a custom sort function like other answers suggest, nor sort it in vanilla JS before using it.

You can sort it like:

... | orderBy: 'this[1]'

to order it by second (index 1) element.

Also you can just ad a minus to reverse it:

... | orderBy: '-this[1]'

Here's an example:

var app = angular.module('helloworld', []);
app.controller('TestController', function () {
    var test = this;
    this.orderIndex = 'this[1]';
    this.data = [
        [ 'A2', 'A3', 'X' ],
        [ 'A1', 'Z', 'VZZ' ]
    ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<table ng-app="helloworld" ng-controller="TestController as test" border="1" cellspacing=0 cellpadding=3>
  <tbody>
    <tr ng-repeat="row in test.data | orderBy:test.orderIndex">
      <td ng-repeat="column in row">{{ column }}</td>
    </tr>
  </tbody>
</table>

EDIT

I couldn't make it work to only manipulate number, but when I put a variable instead of whole orderBy condition, it works. You can replace whole part this[0] with a variable and manipulate that on your own.

So now you would have to find a way to manipulate this string.

Please check edited snippet above to see the idea.

Hope this helps.

Jakub Matczak
  • 15,341
  • 5
  • 46
  • 64
  • Nice ! it looks like the solution I was looking for. However I am now looking to how I can pass a parameter instead of a fixed value. Any suggestion ? – Cheyenne55 Oct 08 '15 at 14:16
  • You are too quick to answer @dragoste :) I cannot manage to pass a parameter, something like this : {{ column }} Do you know what is the syntax for doing this ? – Cheyenne55 Oct 08 '15 at 14:35
0

define a function for orderBy to use which returns the first element of each sub array

Example in earlier post here

Community
  • 1
  • 1
vogomatix
  • 4,856
  • 2
  • 23
  • 46
0

If you're iterating on the html like you said, you can use orderBy and do something like this:

HTML:

<div ng-controller="MyCtrl">
    <div ng-repeat="val in array | orderBy:mySortFunction">{{val}}</div>
</div>

Controller:

function MyCtrl($scope) {
    $scope.array = [[ 'A2', 'A3', 'X' ],[ 'A1', 'Z', 'VZZ' ]];

    $scope.mySortFunction = function(v) {
       return v[0];
    };
}

Fiddle

Omri Aharon
  • 16,959
  • 5
  • 40
  • 58
0

a solution that takes care for alphanumeric comparison like your example:

array = [[ 'A2', 'A3', 'X' ], [ 'A1', 'Z', 'VZZ' ]];

//pattern that takes care of alphanumeric
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
console.log(array.sort(function(a,b){

    
    var aA = a[0].replace(reA, "");
    var bA = b[0].replace(reA, "");
    if(aA === bA) {
        var aN = parseInt(a[0].replace(reN, ""), 10);
        var bN = parseInt(b[0].replace(reN, ""), 10);
        return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
        return aA > bA ? 1 : -1;
    }
}))
maioman
  • 18,154
  • 4
  • 36
  • 42
0

I dont have the permission to comment @dragoste response but i'm putting it here.

@Cheyenne55, to add a parameter by the view you need to add it to the $scope of your controller(that allows you to acess it directly from the view), in the example bellow you can select the parameters by a selector:

JS:

$scope.parameterOptions = [{
    'title':'first',
    'reference': 0
},{
    'title':'second',
    'reference': 1
},{
    'title':'third',
    'reference': 2
}];

$scope.parameterOptions = $scope.parameterOptions[0];

HTML:

<select ng-model="selectedParameter" ng-options="option.title for option in parameterOptions"></select>

<tr ng-repeat="row in test.data | orderBy:'-this[selectedParameter.reference]'"> <td ng-repeat="column in row">{{ column }}   </td> 
0

Well actually I found out the solution thanks to several of your answers.

As I wrote to @dragoste, the thing I was looking for was the use of "'this[0]'" in the orderBy clause of ngRepeat.

However I had another requirement that was to make dynamic the position used to sort the array, ie. instead of "'this[0]'" I needed "'this[index]'" where index is a var.

But after testing, I found that you cannot pass a var in that specific place because the full sentence is actually this :

 ngRepeat="rows in row | orderBy:'this[0]'"

To solve this you need to write that :

 ngRepeat="rows in row | orderBy:index"

And fit this in your controller :

 $scope.index = 'this[' + position + ']';

Where you set the var position through a ng-click or whatsoever