10

Unsorted array [input] :

["> 30 days", "< 7 days", "< 30 days", "< 10 days"];

The format of an elements in array will always be like : </> X days

Requirement :

Above mentioned array should be sorted as per the greater then (>) and lesser then symbol (<) and also keep the number of days in mind (less number of days should come first).

Expected Array [output] :

["< 7 days", "< 10 days", "< 30 days", "> 30 days"];

Tried so far :

I tried Array.sort() function but did not get expected output.

var arr = ["> 30 days", "< 7 days", "< 30 days", "< 10 days"];

var sortedArr = arr.sort();

console.log(sortedArr); // ["< 30 days", "< 10 days", "< 7 days", "> 30 days"]

9
  • 1
    so you need only the sign and the number. is the number always an integer? Commented Jul 18, 2017 at 9:48
  • 1
    @NinaScholz yes number will always be an integer. Commented Jul 18, 2017 at 9:49
  • Is > 10 days higher or lower than < 20 days…? Or does that case not exist? Commented Jul 18, 2017 at 9:54
  • > 10 days should be lower than < 20 days. this case is handled in Nina Scholz solution. Commented Jul 18, 2017 at 10:26
  • 1
    What about > 10 days vs. < 11 days…? Commented Jul 18, 2017 at 10:29

3 Answers 3

15

You could sort by numbers and if a comparison sign is available, then take for the same numerical value the delta of both offsets, which reflects the order of comparison.

var array = ["> 30 days", "< 7 days", "30 days", "< 10 days", "> 10 days", "< 11 days", "42 days", ">= 42 days", "> 42 days", "<= 42 days", "< 42 days"];

array.sort(function (a, b) {
    function getV(s) {
        return {
            value: s.match(/\d+/),
            offset: { '<': -2, '<=': -1, null: 0, '>=': 1, '>': 2 }[s.match(/[<>]={0,1}(?=\s*\d)/)]
        };
    }
    var aa = getV(a),
        bb = getV(b);

    return aa.value - bb.value || aa.offset - bb.offset;
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }


First/former solution

You could parse the string and use it for applying a correction value to the number - then sort accordingly.

{ '>': 0.1, '<': -0.1, null: 0 }[s.match(/[<>](?=\s*\d)/)] + +s.match(/\d+/)

object with correction values

{ '>': 0.1, '<': -0.1, null: 0 }                                    

get the sign with a regular expression and use it as key for the object

                                 s.match(/[<>](?=\s*\d)/)

then add the number part of the string

                                                          + +s.match(/\d+/)

var array = ["> 30 days", "< 7 days", "30 days", "< 10 days"];

array.sort(function (a, b) {
    function getV(s) {
        return { '>': 0.1, '<': -0.1, null: 0 }[s.match(/[<>](?=\s*\d)/)] + +s.match(/\d+/);
    }
    return getV(a) - getV(b);
});

console.log(array);

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

1 Comment

It is working like a champ. Thanks for this solution. can you please explain this line of code { '>': 0.1, '<': -0.1, null: 0 }[s.match(/[<>](?=\s*\d)/)] + +s.match(/\d+/). So that it will helpful for me and other users to solve this type of problem in future by themselves.
0

Another attempt at the problem without regex. I am not good at regex so thought of an alternative way.

         // Attempt to sort without regex.
         var array = ["> 30 days", "< 7 days", "< 30 days", "< 10 days"];

         array.sort(function(a,b){ 
           var first = a.split(" "); 
           var second = b.split(" ");
           if(first[0] < second[0]) {  
               return false; 
           } else if(first[0] > second[0]){ 
               return true; 
           } else { 
              var intFirst = parseInt(first[1]);
              var intSecond = parseInt(second[1]);
              if(intFirst < intSecond){
                return false; 
              } else if(intFirst >= intSecond) {
                return true;
              }
           }
         });
         
         console.log(array);

1 Comment

Fixed the problem. :)
0

Try this code:

customSort();

var arr = ["> 30 days", "< 7 days", "30 days", "< 10 days"];
var arr2 = ["> 30 days", "< 7 days", "< 30 days", "< 10 days"];
		
console.log(customSort(arr));
console.log(customSort(arr2));
		
function customSort(array){
    function getNumber(str) {
        var a={'>': 0.1, '<': -0.1, null: 0};
        return a[str.match(/[<>](?=\s*\d)/)] + Number(str.match(/\d+/)[0]);
    }
    return array.sort(function(a, b){
        return getNumber(a)-getNumber(b);
    });
}

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.