Tim Liberty
Tim Liberty

Reputation: 2129

Javascript sorting array

I am trying to write a sort function where the list should have the 1st item whose type = 'text/xml' but after that all items should be sorted by name ascending.

I will have just 2 types in my dataset: text/xml and img/jpg

Here is my code:

var fileArray = [
    {"name":'1101.jpg', type:"img/jpg"},
  {"name":'1301.jpg', type:"img/jpg"},
  {"name":'1001.jpg', type:"img/jpg"},
  {"name":'1005.jpg', type:"img/jpg"},
  {"name":'1201.jpg', type:"img/jpg"},
  {"name":'1500.jpg', type:"img/jpg"},
  {"name":'MyFile.xml', type:"text/xml"}, 
  {"name":'1700.jpg', type:"img/jpg"},
 ];

 fileArray.sort(function (a, b) { return b.type >= a.type });

        fileArray.sort(function (a, b) {
            if (a.type == 'text/xml') {
                return -1000;
            }
            else {
                var rc = 0;
                var c = a.name;
                var d = b.name;
                if (c < d)
                    rc = -1;
                if (c > d)
                    rc = 1;
                return rc;
            }
        });

console.log(fileArray);

Here is my jsfiddle: https://jsfiddle.net/mofuqada/1/

It seems to work with the sample data. However, wanted to ask if you see any issue in the code where it might not work with 100's of files

Upvotes: 1

Views: 58

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386578

You could use a check and use it as a value for sorting.

(a.type !== 'text/xml') - (b.type !== 'text/xml')

This part can be splitted into

a.type !== 'text/xml'

for a and for b

It is a simple check for unequality and return a boolean value like true or false. In the case for 'text/xml' false and otherwise true.

But I need numerical values and 'text/xml' must comes with a smaller value than other strings. So it does with conversion of false to 0 and true to 1. The difference is the value for sorting.

Later the name is only compared if the previous calculation is falsy, 0 in this case.

var fileArray = [{ name: '1101.jpg', type: "img/jpg" }, { name: '1301.jpg', type: "img/jpg" }, { name: '1001.jpg', type: "img/jpg" }, { name: '1005.jpg', type: "img/jpg" }, { name: '1201.jpg', type: "img/jpg" }, { name: '1500.jpg', type: "img/jpg" }, { name: 'MyFile.xml', type: "text/xml" }, { name: '1700.jpg', type: "img/jpg" }];

fileArray.sort(function (a, b) {
    return (a.type !== 'text/xml') - (b.type !== 'text/xml') || a.name.localeCompare(b.name);
});

console.log(fileArray);

Upvotes: 1

Rajesh
Rajesh

Reputation: 24915

You can use an arithmetic based Rank calculator which can be then used to sort:

Note I have assumed that if there are multiple files with text/xml then they should be sorted by name as well. I have added an extra object with filename File.xml to depict the same.

Sample

var fileArray=[{name:"1101.jpg",type:"img/jpg"},{name:"1301.jpg",type:"img/jpg"},{name:"1001.jpg",type:"img/jpg"},{name:"1005.jpg",type:"img/jpg"},{name:"1201.jpg",type:"img/jpg"},{name:"1500.jpg",type:"img/jpg"},{name:"MyFile.xml",type:"text/xml"},{name:"File.xml",type:"text/xml"},{name:"1700.jpg",type:"img/jpg"}];

fileArray.sort(function(a,b){
  var fileRank = a.type === b.type? 0 : a.type === "text/xml" ? -10 : 10;
  return (a.name > b.name ? 1: a.name < b.name ? -1 : 0) + fileRank;
})
  
console.log(fileArray)

Upvotes: 1

ofer goli
ofer goli

Reputation: 91

Just do

fileArray.sort(function(a,b){
    return a.name > b.name;
 }).sort(function(a,b){
    return a.type < b.type;
});

enjoy

Upvotes: 0

Related Questions