0

I've an array like this:

[{"category_id":101,"category_name":"abc","state":null},
{"category_id":204,"category_name":"test","state":null},
{"category_id":7,"category_name":"pqr","state":"1526985908122"},
{"category_id":103,"category_name":"User","state":null},
{"category_id":2,"category_name":"System","state":null},
{"category_id":205,"category_name":"xyz","state":"1526985908019"},
{"category_id":203,"category_name":"dash","state":null},
{"category_id":4,"category_name":"hello","state":null},
{"category_id":206,"category_name":"demo","state":"1526985908187"},
{"category_id":6,"category_name":"about","state":null},
{"category_id":3,"category_name":"role","state":null}]

I want to sort this array based on the value of state property like you can see state has null and some numeric value here.

If state != null then sort in ascending order and if state == null then sort in descending order (based on category id)

So the actual result should be like this:

[{"category_id":205,"category_name":"xyz","state":"1526985908019"},
{"category_id":7,"category_name":"pqr","state":"1526985908122"},
{"category_id":206,"category_name":"demo","state":"1526985908187"},
{"category_id":204,"category_name":"test","state":null},
{"category_id":203,"category_name":"dash","state":null},
{"category_id":103,"category_name":"User","state":null},
{"category_id":101,"category_name":"abc","state":null},
{"category_id":6,"category_name":"about","state":null},
{"category_id":4,"category_name":"hello","state":null},
{"category_id":3,"category_name":"role","state":null},
{"category_id":2,"category_name":"System","state":null}]

So it should sort first 3 records based on state value in ascending order and other records based on null value in descending order based on category id.

This is what I've tried referencing this article: https://technology.amis.nl/2007/08/24/how-to-fix-your-number-sorting-problems-in-javascript/

var ALMOST_ZERO = -0.00000001;  
records.sort(function(a,b){         
    console.log(`comparing ${a.state},${b.state}`);
    var left = a.state != null ? a.state : ALMOST_ZERO;
    var right = b.state != null ? b.state : ALMOST_ZERO;    
    return right-left;
});

Any help would be appreciated.

Thanks

3
  • yes. updated code. Commented May 23, 2018 at 5:15
  • So what happens when you try that sort function? Commented May 23, 2018 at 5:16
  • 1
    @JJJ: its sorting everything in descending order Commented May 23, 2018 at 5:18

4 Answers 4

7

Here's a concise version. By using ||, whenever the upper expression(s) evaluate to 0, it moves on to test the next lower expression:

const arr=[{"category_id":101,"category_name":"abc","state":null},{"category_id":204,"category_name":"test","state":null},{"category_id":7,"category_name":"pqr","state":"1526985908122"},{"category_id":103,"category_name":"User","state":null},{"category_id":2,"category_name":"System",state:null},{"category_id":205,"category_name":"xyz","state":"1526985908019"},{"category_id":203,"category_name":"dash","state":null},{"category_id":4,"category_name":"hello","state":null},{"category_id":206,"category_name":"demo","state":"1526985908187"},{"category_id":6,"category_name":"about","state":null},{"category_id":3,"category_name":"role","state":null}]

arr.sort((a, b) => (
  (a.state === null) - (b.state === null)
  || a.state - b.state
  || b.category_id - a.category_id
));
console.log(arr);

Console version:

enter image description here

ES5 version:

var arr = [{ "category_id": 101, "category_name": "abc", "state": null }, { "category_id": 204, "category_name": "test", "state": null }, { "category_id": 7, "category_name": "pqr", "state": "1526985908122" }, { "category_id": 103, "category_name": "User", "state": null }, { "category_id": 2, "category_name": "System", state: null }, { "category_id": 205, "category_name": "xyz", "state": "1526985908019" }, { "category_id": 203, "category_name": "dash", "state": null }, { "category_id": 4, "category_name": "hello", "state": null }, { "category_id": 206, "category_name": "demo", "state": "1526985908187" }, { "category_id": 6, "category_name": "about", "state": null }, { "category_id": 3, "category_name": "role", "state": null }];

arr.sort(function (a, b) {
  return (a.state === null) - (b.state === null) || a.state - b.state || b.category_id - a.category_id;
});
console.log(arr);

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

7 Comments

output is correct but when I'm performing this on chrome console then its not sorting properly
Works for me in the console.
it is sorting like this: 205, 2, 206,204,203,7,101,6,4,3,103
Just checked the response : typeof(records) is object. is it because of this??
Arrays are objects. See edit for how it looks in my console; sounds like your issue is elsewhere
|
1

@sky, try below solution

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
var test= [{"category_id":101,"category_name":"abc","state":null},
{"category_id":204,"category_name":"test","state":null},
{"category_id":7,"category_name":"pqr","state":"1526985908122"},
{"category_id":103,"category_name":"User","state":null},
{"category_id":2,"category_name":"System","state":null},
{"category_id":205,"category_name":"xyz","state":"1526985908019"},
{"category_id":203,"category_name":"dash","state":null},
{"category_id":4,"category_name":"hello","state":null},
{"category_id":206,"category_name":"demo","state":"1526985908187"},
{"category_id":6,"category_name":"about","state":null},
{"category_id":3,"category_name":"role","state":null}];

 function sortByKeyAsc(array, key) {
        return array.sort(function (a, b) {
            var x = a[key]; var y = b[key];
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }
function sortByKeyDesc(array, key) {
    return array.sort(function (a, b) {
        var x = a[key]; var y = b[key];
        return ((x > y) ? -1 : ((x < y) ? 1 : 0));
    });
}
console.log(sortByKeyDesc(test,"state")  );
</script>
</head>
<body>

</body>
</html>

Comments

1

Try following

var arr = [{"category_id":101,"category_name":"abc","state":null},{"category_id":204,"category_name":"test","state":null},{"category_id":7,"category_name":"pqr","state":"1526985908122"},{"category_id":103,"category_name":"User","state":null},{"category_id":2,"category_name":"System",state:null},{"category_id":205,"category_name":"xyz","state":"1526985908019"},{"category_id":203,"category_name":"dash","state":null},{"category_id":4,"category_name":"hello","state":null},{"category_id":206,"category_name":"demo","state":"1526985908187"},{"category_id":6,"category_name":"about","state":null},{"category_id":3,"category_name":"role","state":null}];

arr.sort((a,b) => {
  // If both null, sort by category_id descending
  if(!a.state && !b.state) return b.category_id - a.category_id;
  // if first value is null, swap
  else if(!a.state) return 1;
  // if second value is null, no change 
  else if (!b.state) return -1;
  // if both have values sort by state ascending.
  else return a.state - b.state;
})

console.log(arr);

Comments

1

var data = [{
        "category_id": 101,
        "category_name": "abc",
        "state": null
    },
    {
        "category_id": 204,
        "category_name": "test",
        "state": null
    },
    {
        "category_id": 7,
        "category_name": "pqr",
        "state": "1526985908122"
    },
    {
        "category_id": 103,
        "category_name": "User",
        "state": null
    },
    {
        "category_id": 2,
        "category_name": "System",
        "state": null
    },
    {
        "category_id": 205,
        "category_name": "xyz",
        "state": "1526985908019"
    },
    {
        "category_id": 203,
        "category_name": "dash",
        "state": null
    },
    {
        "category_id": 4,
        "category_name": "hello",
        "state": null
    },
    {
        "category_id": 206,
        "category_name": "demo",
        "state": "1526985908187"
    },
    {
        "category_id": 6,
        "category_name": "about",
        "state": null
    },
    {
        "category_id": 3,
        "category_name": "role",
        "state": null
    }
];


var valueWithoutNull = data.filter(val => val.state != null);
var valueWithNull = data.filter(val => val.state == null);

valueWithoutNull = valueWithoutNull.sort((a, b) => a.state - b.state);

var result = [...valueWithoutNull, ...valueWithNull];

console.log(result);

var data = [{
        "category_id": 101,
        "category_name": "abc",
        "state": null
    },
    {
        "category_id": 204,
        "category_name": "test",
        "state": null
    },
    {
        "category_id": 7,
        "category_name": "pqr",
        "state": "1526985908122"
    },
    {
        "category_id": 103,
        "category_name": "User",
        "state": null
    },
    {
        "category_id": 2,
        "category_name": "System",
        "state": null
    },
    {
        "category_id": 205,
        "category_name": "xyz",
        "state": "1526985908019"
    },
    {
        "category_id": 203,
        "category_name": "dash",
        "state": null
    },
    {
        "category_id": 4,
        "category_name": "hello",
        "state": null
    },
    {
        "category_id": 206,
        "category_name": "demo",
        "state": "1526985908187"
    },
    {
        "category_id": 6,
        "category_name": "about",
        "state": null
    },
    {
        "category_id": 3,
        "category_name": "role",
        "state": null
    }
];

data = data.sort(function(a, b) {
    if (a.state == null)
        return 1;
    if (b.state == null)
        return -1;

    return a.state - b.state;
});

console.log(data);

2 Comments

Thanks for answer but its not matching with desired output. It should sort state (if not null) in asc and null (if state null) then in desc.
I updated second option and going to check your concern in first one.

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.