-1

I have an idea on how to improve some code but that would require using arrays and these arrays have to have a certain sorting order.

I have a given array: var p = ['skewX', 'translateY', 'scale', 'rotateX'];.

I need these strings sorted inside the array on a pattern:

0 translate, 1 rotate, 2 skew, 3 scale

or

0 ordered translations, 1 ordered rotations, 2 ordered skews, 3 ordered scales

where

index and string

Question: is it possible to sort these arrays based on this pattern?

Thanks so much.

thednp
  • 4,401
  • 4
  • 33
  • 45
  • 1
    Yes. You can write your own comparison function. See: [How to define custom sort function in javascript?](http://stackoverflow.com/questions/5002848/how-to-define-custom-sort-function-in-javascript) – GolezTrol Oct 25 '15 at 06:37
  • Thanks for the suggestion, but I don't understand the `sort()` method as I fail to see/understand how `scaleX > rotateX` for instance. Can you please forge an epic answer for me please? Worth the challenge. – thednp Oct 25 '15 at 06:48
  • Also your suggestion has nothing to do with a pattern. – thednp Oct 25 '15 at 06:54
  • Your question neither. It's just a custom sorting. You will have to write the logic for custom comparison yourself. But okay, I'll bit, and I've taken the 'challenge' to do your work (see answer below). Please next time, *you* take the challenge to spend more than 11 minutes trying when somebody tries to point you in the right direction. ;-) – GolezTrol Oct 25 '15 at 07:05
  • The challenge is not to do my work, but to make me understand (and I hope many others) what I cannot explain myself. I never had this situation before so my question sounds no different than any n00b question, terrible, so THANK YOU. – thednp Oct 25 '15 at 10:25

2 Answers2

2

The callback function doesn't sort itself. It just needs to compare any two items that are passed to it. So you have to write the logic that translates strings starting with 'translate' come before strings starting with 'rotate'.

// Very simple, rudimentary function to translate a type to number. Improve at will.
function typeIndex(x) {
  if (x.indexOf('translate') > -1) return 0;
  if (x.indexOf('rotate') > -1) return 1;
  if (x.indexOf('skew') > -1) return 2;
  if (x.indexOf('scale') > -1) return 3;
  return 1000; // Unknown
}

var p = ['skewX', 'rotateY', 'rotateZ', 'translateY', 'scale', 'rotateX', 'ordered skewing'];


// Sort array using callback;
p.sort(function(a, b){
  // First compare the difference based on type.
  var result = typeIndex(a) - typeIndex(b);
  
  // If the difference is 0, they are of the same type. Compare the whole string.
  if (result == 0) 
    result = a.localeCompare(b);
  
  return result;
});

console.log(p);
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Thanks man I'll give it a go, but I think the other answer here is much better :) – thednp Oct 25 '15 at 10:15
  • If you think so, then please accept that one, but I think it's less readable with that string of abbreviations, and less flexible too. You would have to completely rewrite it if you want to add 'transpose' to the list, for instance. Also, my version does a secondary sorting on the alphabetical value if the first part is the same. But it's a common beginner mistake to think that less code is always better. ;-) – GolezTrol Oct 25 '15 at 10:54
  • I think you are the one who downvoted. It's ok, I will mark your answer as answered because you also provided most information. Thanks again. – thednp Oct 25 '15 at 11:51
1

The sort function can be based on the words you want to sort on in sequence, provided they have unique sequences of characters:

var p = ['skewX', 'translateY', 'scale', 'rotateX'];

p.sort(function(a, b) {
  var order = 'transrotaskewscal';
  return order.indexOf(a.slice(0,4)) - order.indexOf(b.slice(0,4));
});

document.write(p);
RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thank you so much, I don't have to test it, I can see it here it works wonderful :). Would this still work for something like this `var p = ['skewX', 'translateY', 'scale', 'rotateX', 'rotateZ']`? My first guess is that it does, those slices `0.4` seem to match the `trans`+`rota`+`skew`+`scal`, right? – thednp Oct 25 '15 at 10:15
  • Yes, that was the idea. If you have to do a lot of this, *indexOf* might be a bit slower than object property lookup, so you could use `var p = {trans:0,rota:1, ...}`. Whatever suits. – RobG Oct 25 '15 at 22:45