4
var myArray = [
    '_aaaa_2013-09-25_ssss9.txt',
    '_aaaa_2013-09-25_ssss8.txt',
    '_aaaa_2013-09-26_ssss1.txt',
    '_aaaa_2013-09-25_ssss10.txt',
    '_aaaa_2013-09-26_ssss2.txt',
    '_aaaa_2013-09-25_ssss13.txt',
    '_aaaa_2013-09-25_ssss5.txt',
    '_aaaa_2013-09-25_ssss6.txt',
    '_aaaa_2013-09-25_ssss7.txt'
];

I need to sort the array by date and number.

Result should be

var result = [
    '_aaaa_2013-09-25_ssss5.txt',
    '_aaaa_2013-09-25_ssss6.txt',
    '_aaaa_2013-09-25_ssss7.txt',
    '_aaaa_2013-09-25_ssss8.txt',
    '_aaaa_2013-09-25_ssss9.txt',
    '_aaaa_2013-09-25_ssss13.txt',
    '_aaaa_2013-09-26_ssss1.txt',
    '_aaaa_2013-09-26_ssss2.txt'
];

I have tried below code.this will do the sort by date only but i need to sort by the number which is before '.txt'.How can i do this.

myArray.sort(function (a, b) {

    var timeStamp1 = a.substring(a.indexOf('_aaaa') + 6, a.indexOf('_ssss'));
    var timeStamp2 = b.substring(b.indexOf('_aaaa') + 6, b.indexOf('_ssss'));
    timeStamp1 = new Date(Date.UTC(timeStamp1[0], timeStamp1[1], timeStamp1[2]));
    timeStamp2 = new Date(Date.UTC(timeStamp2[0], timeStamp2[1], timeStamp2[2]));

    return (timeStamp1 > timeStamp2) ? 1 : (timeStamp2 > timeStamp1 ? -1 : 0);

});
8
  • @sachin: You can compare any YMD dates by number. You could compare your YYYY-MM-DD dates even as strings, but that's not needed here. And comparing numbers is trivial (search for it if you don't know it) Commented Sep 25, 2013 at 18:35
  • I just tried the accepted solution in the link Ela posted and Bergi suggested for your use case, it sorted as you desire. Commented Sep 25, 2013 at 18:39
  • @Bergi i have tried that but that is not working. Commented Sep 26, 2013 at 7:34
  • return (timeStamp1 > timeStamp2) ? 1 : 0; Commented Sep 26, 2013 at 7:44
  • 1
    Never ever duplicate your own question only because you didn't get an answer so far. Instead edit and improve your existing question. Commented Sep 26, 2013 at 8:41

4 Answers 4

1

You could do it like this:

var re = /^_aaaa_(\d\d\d\d-\d\d-\d\d)_ssss(\d+)\.txt$/;

var result = myArray.slice().sort( function( a, b ) {
    var aa = a.match(re), bb = b.match(re);
    return(
        aa[1] < bb[1] ? -1 :
        aa[1] > bb[1] ? 1 :
        aa[2] - bb[2]
    );
});

Note the use of .slice() to create a copy of the array. This can be omitted if you want to sort the original array in place. (Thanks to @DerFlatulator for the reminder!)

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

4 Comments

Hi i tried this but im getting error in this line : aa[1] < bb[1] ? -1 : TypeError: Cannot read property '1' of null
What that error means is that the regular expression did not match the text in the array element. So it would seem your data must be different from what you posted in your question. If you paste your definition of myArray into the Chrome console and then paste my code above, the value of result will be what you were looking for. What is different in your data or code?
@DerFlatulator my data is : cccc_aaaa_2013-09-26_ssss1.txt
Please note that this answer will modify myArray as well as store the result in result. If you want to make a shallow copy of the array, use something akin to var result = myArray.slice().sort(...); Also, why am I tagged in this answer?
1

This worked for me.

myArray.sort(function (a, b) {
    var a_s = a.substring(0, a.indexOf('ssss') + 4);
    var a_n = a.substring(a.indexOf('ssss') + 4, a.indexOf('.txt'));
    var b_s = b.substring(0, b.indexOf('ssss') + 4);
    var b_n = b.substring(b.indexOf('ssss') + 4, b.indexOf('.txt'));
    if (a_s < b_s)
        return -1;
    if (a_s > b_s)
        return 1;
    return parseInt(a_n) - parseInt(b_n);
});

jsFiddle

4 Comments

i tried this but i'm not getting exact output..first i need to sort by date then by number which is before '.txt'.Now its sorting only by date not by number
Check the jsFiddle link at the end. The panel on the (bottom-)right shows the output, it sorts by string then number, which is the same as date then number (so long as dates and months are padded left with 0, e.g. 07 = July)
Please move your answer over to stackoverflow.com/questions/19012468/…
If you think it's a well answer (worth the action), move it to the dupe of the dupe.
0

Sort by numeric value within strings.

This assumes:

  • numbers are integers
  • every string is different
  • dates may be sorted as numbers (year,month,day)

["aa_123","aa_13","aa_2","aa_22_bb_23","aa_22_bb_3"].sort( function ( a , b ) {

    var as = a.split(/([0-9]+)/); // splits string retaining separators
    var bs = b.split(/([0-9]+)/);
    var i,c = Math.min(as.length,bs.length);
    for ( i=0;i<c && as[i]===bs[i];++i ) ;
    var an = (i&1)?+as[i]:as[i]; // separators (digits) always at odd index
    var bn = (i&1)?+bs[i]:bs[i];
    return (an<bn)?-1:1; // assumes every string different

} );

result:

[
  "aa_2",
  "aa_13",
  "aa_22_bb_3",
  "aa_22_bb_23",
  "aa_123"
]

Comments

0

This, extracts the numbers from the given string, and puts a given weight on each numerical part. So you can sort it in any order with given priorities for Count, Day, Month, Year.

function weightedNumSort(myArray,weightNum,weightString) {    
    var WEIGHTS_NUM = weightNum || [1,2,4,3]; //[YEAR,MONTH,DAY,COUNT], You can pass an array with appropriate weights for the number at the given position in the text, e.g year is the first Number
    var WEIGHT_STRING = weightString || 1; //And a weight for the string value. If none get passed, default weights are used

        function weightedSum (a,b,i) {
            return ( a  +  b * ( WEIGHTS_NUM [i-1] || 1 ));
        }

    myArray = myArray.slice().sort(function (a, b) {
        var reg = /(\d+)/g //A regex to extract the numerical part

        var lNum = a.match(reg) //Extract the numerical parts we now have an array ["2013","09","26","2"]

        var rNum = b.match(reg)

        var delta = Array.apply(null,{length:lNum.length+1});
            delta [0] = 0; //add a 0 at the beginning, for convenience with the reduce function

        for (var i=0,j=lNum.length; i < j; i++) {
            var value = lNum[i] - rNum[i];
            value = ~~ (value / Math.abs (value)) // 1 for positive values, 0 for 0 , -1 for negative values, to make weighting easier
            delta[i+1] = value;
        }

        var weightedNumValue = delta.reduce (weightedSum) //Put a weight on the number parts.
        var weightedStrValue = WEIGHT_STRING * ( a > b ? 1 : a < b ? -1 : 0 )    
        return weightedNumValue + weightedStrValue //Add the weighted values and we have a positive or negative value with a correct weight on the numerical parts
    })
    return  myArray
}

Output

console.log (
   weightedNumSort (myArray)    
) /*
[
  "_aaaa_2013-09-25_ssss5.txt",
  "_aaaa_2013-09-25_ssss6.txt",
  "_aaaa_2013-09-25_ssss7.txt",
  "_aaaa_2013-09-25_ssss8.txt",
  "_aaaa_2013-09-25_ssss9.txt",
  "_aaaa_2013-09-25_ssss10.txt",
  "_aaaa_2013-09-25_ssss13.txt",
  "_aaaa_2013-09-26_ssss1.txt",
  "_aaaa_2013-09-26_ssss2.txt"
]*/

and a Fiddle

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.