Function to sort MultiDimensional Arrays

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

Andrew

Function to sort MultiDimensional Arrays

Post by Andrew »

Anyone got a function to sort say an array with say each member of the array is an array of three items eg

tArray[0] = [21,15,6];
tArray[1] = [12,45,70];
etc

Sort the array by tArray[1] and within that sort, sort by tArray[0]

I can make one myself but if anyone has already done this it would save me a bit of time (actually might be quicker to look for a php version and adapt it).

Andrew
xbytor

Function to sort MultiDimensional Arrays

Post by xbytor »

Here ya go.
Code: Select allfunction sortFtn(a, b) {
  var c = a[1] - b[1];
  return c ? c : a[0] - b[0];
};

tArray = [];
tArray[0] = [21,15,6];
tArray[1] = [12,45,70];
tArray[2] = [12,35,70];
tArray[3] = [1,4,7];
tArray.sort(sortFtn);

var s = '';;
for (var i = 0; i < tArray.length; i++) {
  s += tArray + '\r';
}
alert(s);


This sorts column 1 then column 0. Switch the indexes in the sort function to get the reverse effect. Change 'a[] - b[]' to 'b[] - a[]' to reverse the sort.
Andrew

Function to sort MultiDimensional Arrays

Post by Andrew »

That's great X, so does this look OK for an lexicographical sort where any numbers are converted to strings (seems to work):

Code: Select allfunction sortFtn(a, b) {
   if (a[0].toString() > b[0].toString()) var c = 1;
   else if (a[0].toString() == b[0].toString()) var c = a[1].toString() > b[1].toString();
   else var c = -1;
   return c;
};

tArray = [];
tArray[0] = ['c','f',6];
tArray[1] = ['a','f',70];
tArray[2] = ['c','a',70];
tArray[3] = ['d','g',7];
tArray[4] = ['c',35,71];
tArray[5] = ['c','g',7];
tArray.sort(sortFtn);

var s = '';;
for (var i = 0; i < tArray.length; i++) {
  s += tArray + '\r';
}
alert(s);
xbytor

Function to sort MultiDimensional Arrays

Post by xbytor »

For a lexical sort, there is a predefined method, String.localeCompare, that should simplify your sort function a bit:

Code: Select allfunction sortFtn(a, b) {
  var c = a[0].toString().localeCompare(b[0].toString());
  return c ? c : a[1].toString().localeCompare(b[1].toString());
};


This is roughly equivalent to your sort function. String.localeCompare does a bit better with unicode than a straight String comparison, 'though that shouldn't really be an issue if you're not using 16bit unicode characters.
Andrew

Function to sort MultiDimensional Arrays

Post by Andrew »

To tighten this up further, it would be nice to be able to specify the sub-array indexes as parameters of the compare function, but I am having trouble getting it to work, since when we specify the compare we do not pass parameters at all - the a,b appear to be taken as given. Something like

Code: Select allfunction sortFtn(a, b, i, j) {
  var c = a - b;
  return c ? c : a[j] - b[j];
};

tArray.sort(sortFtn(a,b,i,j));

Except, of course that fails since a,b are not defined.

Andrew
xbytor

Function to sort MultiDimensional Arrays

Post by xbytor »

Here's one way of doing it.

Code: Select allsortFtnType2 = function(i, j) {
  var f = sortFtnType2;      // shorthand
  var ftn = function(a, b) {
     var c = a[f.idx1] - b[f.idx1];
     return c ? c : a[f.idx2] - b[f.idx2];
  };

  f.idx1 = i;
  f.idx2 = j;

  return ftn;
}

tArray.sort(sortFtnType2(i,j));

You could probably tweak it to take an aribitrary number of indexes instead of just two.