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.

3
  • use Array.sort(function(){}) Commented Oct 8, 2015 at 13:43
  • you are iterating over it in html? can you show the html if you have it? Commented Oct 8, 2015 at 13:44
  • I did not said it precisely but I am iterating over the array with ngRepeat (that is why I wrote "... | orderBy..." and I want the sort to be dynamic so I do not want a static sort Commented Oct 8, 2015 at 13:46

8 Answers 8

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]} );

Sign up to request clarification or add additional context in comments.

Comments

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;
    }
})

Comments

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.

2 Comments

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 ?
You are too quick to answer @dragoste :) I cannot manage to pass a parameter, something like this : <tr ng-repeat="row in test.data | orderBy:'-this[myParameter]'"> <td ng-repeat="column in row">{{ column }}</td> </tr> Do you know what is the syntax for doing this ?
0

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

Example in earlier post here

Comments

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

Comments

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;
    }
}))

Comments

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> 

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.