3

I'm trying to sort an array based on the first digit encountered in the title.

My attempt was replacing the non-numeric characters with '' (title.replace(/\D/g, ''). It gives me back the digits but I'm not sure how to sort the array from this point.

So, test0 first followed by test1, test2 and test3.

model = [
  {
    "title": "test3"
  },
  {
    "title": "test1"
  },
  {
    "title": "test2"
  },
  {
    "title": "test0"
  }
];
Mithrilhall
  • 1,485
  • 8
  • 33
  • 52
  • 1
    Closely related: [Sorting an array of JavaScript objects](http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects) and [Sorting objects in an array by a field value in JavaScript](http://stackoverflow.com/questions/1129216/sorting-objects-in-an-array-by-a-field-value-in-javascript). You already know how to transform the field to your liking, so simply perform that transformation on the field in your comparison function. – apsillers Dec 29 '14 at 21:32

3 Answers3

5

You can your use regex within Javascript's sort function, like the following.

var model = [
    {
        "title": "test3"
    },
    {
        "title": "test1"
    },
    {
        "title": "test2"
    },
    {
        "title": "test0"
    }
];

Update:

As Danilo Valente stated in comments, if your integer begins with a 0, you need to extract the first 0 from the string. Since 02 => 0

model.sort(function (a, b) {
    //Strips out alpha characters
    a = a.title.replace(/\D/g, '');
    b = b.title.replace(/\D/g, '');

    //sets value of a/b to the first zero, if value beings with zero.
    //otherwise, use the whole integer.
    a = a[0] == '0' ? +a[0] : +a;
    b = b[0] == '0' ? +b[0] : +b;

    return a - b;
});
Wondercricket
  • 7,651
  • 2
  • 39
  • 58
  • 2
    He wants to sort based on the first digit, but in your case if we had `"title02"` it would appear after `"test1"`. – Danilo Valente Dec 29 '14 at 21:36
  • @DaniloValente Ah, yes. Thanks for pointing that out! I updated my code to cast `a` and `b` as integers. – Wondercricket Dec 29 '14 at 21:39
  • First you have to extract only the first digit so `02 => 0` and then compare both: `0 < 1`. – Danilo Valente Dec 29 '14 at 21:43
  • @DaniloValente I tested the updated code before I posted it, and it sorted properly for me. – Wondercricket Dec 29 '14 at 21:43
  • I did too, and it still doesn't work. Replace `"test0"` with `"test02"` and you'll see. The result should be `["test02", "test1", "test2", "test3"]`, but instead it returns `["test1", "test2", "test02", "test3"]`. – Danilo Valente Dec 29 '14 at 21:45
  • @DaniloValente oh, I see what you mean now! That was a derp on my end, it "looked" correct when I ran it :) I'll update my code appropriately. – Wondercricket Dec 29 '14 at 21:50
4

var model = [{
  "title": "test3"
}, {
  "title": "test1"
}, {
  "title": "test2"
}, {
  "title": "test02"
}, {
  "title": "test0"
}];

// pass a custom sort fn to `.sort()`
var sortedModel = model.sort(function(a, b) {
  // just get the first digit
  return a.title.match(/\d/) - b.title.match(/\d/);
});

console.log(sortedModel);

// [ { title: 'test02' },
//   { title: 'test0' },
//   { title: 'test1' },
//   { title: 'test2' },
//   { title: 'test3' } ]
brbcoding
  • 13,378
  • 2
  • 37
  • 51
0

Since you want to sort based only on first digit, you can call .sort with a custom function and then use a simple regex to find the first digit:

model.sort(function (a, b) {
    var da = a.title.match(/\d/);
    var db = b.title.match(/\d/);
    return parseInt(da) - parseInt(db);
});
Danilo Valente
  • 11,270
  • 8
  • 53
  • 67