Copy link to clipboard
Copied
Since my system is English the locale sort does not provide any benefit.
sNamen = ['Käfer', 'côte', 'Bären', 'küssen', 'Kasimir','coté', 'analog', 'Ähnlich', 'Äpfel'];
$.writeln (sNamen.sort());
$.writeln (sNamen.sort(function (a, b) { return a.localeCompare(b)}));
Results in
Bären,Kasimir,Käfer,analog,coté,côte,küssen,Ähnlich,Äpfel
Bären,Kasimir,Käfer,analog,coté,côte,küssen,Ähnlich,Äpfel
On a German or French system I expect a different order in t he second result line
Can someone with such a locale prlease test?
And do you know how I should extend the sort function to get the uppercase and lowercase letters together: A, Ä, a, ä, B, b, C, c, ç, ... ?
Copy link to clipboard
Copied
Hi Klaus,
Javascript sorts words/strings by their charactercodes.
So there's no parameter to sort it depending on language.
I have a function that allows me to specify the order in which I want to sort.
I'll post the code tomorrow. Today I am too tired 😉
In the meantime, you can write down the order you would like.
Something like this: a,A,ä,Ä,à,b,B,c,C, d,D,e,E,é,è ...........
See you tomorrow
Copy link to clipboard
Copied
Thanks Klaus for this offer,
But IMHO the function localeCompare shoule observe the locale setting of t he system (or FM ?).
sNamen.sort(function (a, b) { return a.localeCompare(b)});
However, Your function obviously is more universal. So I can set up the proper lexical sort depending on the FM-UI language.
Copy link to clipboard
Copied
Instead of localCompare, use Intl.Collator(lang).compare:
function letterSort(lang, letters) {
letters.sort(new Intl.Collator(lang).compare);
return letters;
}
sNamen = ['Käfer', 'côte', 'Bären', 'küssen', 'Kasimir','coté', 'analog', 'Ähnlich', 'Äpfel'];
console.log(letterSort('de', sNamen));
// expected output: Array ["a", "ä", "z"]
console.log(letterSort('sv', sNamen));
// expected output: Array ["a", "z", "ä"]
Returns:
// console.log(letterSort('de', sNamen));
["Ähnlich", "analog", "Äpfel", "Bären", "coté", "côte", "Käfer", "Kasimir", "küssen"]
// console.log(letterSort('sv', sNamen));
["analog", "Bären", "coté", "côte", "Kasimir", "küssen", "Käfer", "Ähnlich", "Äpfel"]
Also see Intl.
Copy link to clipboard
Copied
Thank You Stefan,
These nice things are not implemented in ExtendScript (as localeCompare is).
Unfortuantely the JS implementation in ES is still that of 1999...
Copy link to clipboard
Copied
Ah, I was not aware that you were talking about ExtendScript.
Copy link to clipboard
Copied
Here is my sort function. You can define the sort order in any way.
You can adjust the sort order to your needs.
var SortOrder1 = "A,Ä,B,C,D,E,F,G,H,I,J,K,L,M,N,Ö,O,P,Q,R,S,T,U,Ü,V,W,X,Y,Z,a,ä,b,c,d,e,f,g,h,i,j,k,l,m,n,o,ö,p,q,r,s,t,u,ü,v,w,x,y,z"; // UPPER CASE first
var SortOrder2 = "A,Ä,a,ä,B,C,c,D,d,E,e,é,é,d,F,f,G,g,H,h,I,i,J,j,K,k,L,l,M,m,N,n,O,ô,o,Ö,ö,P,p,Q,q,R,r,S,s,T,t,U,u,Ü,ü,V,v,W,w,X,x,Y,y,Z,z,"; //Alternating upper and lower case containing accents
var SortOrder3 = "A,Ä,a,ä,B,C,c,D,d,E,e,é,é,d,F,f,G,g,H,h,I,i,J,j,K,k,L,l,M,m,N,n,O,o,ô,Ö,ö,P,p,Q,q,R,r,S,s,T,t,U,u,Ü,ü,V,v,W,w,X,x,Y,y,Z,z,"; //swapped "o" and "ô"
var aNames = ['Käfer', 'côte', 'Bären', 'küssen', 'Kasimir','coté', 'analog', 'Ähnlich', 'Äpfel'];
BubbleSort(aNames,SortOrder1);
$.writeln ("------------ UPPERCASE first");
$.writeln (aNames.join("\n"));
BubbleSort(sNamen,SortOrder2);
$.writeln ("------------ Alternating upper and lower case");
$.writeln (sNamen.join("\n"));
BubbleSort(sNamen,SortOrder3);
$.writeln ("------------ swapped o");
$.writeln (sNamen.join("\n"));
function BubbleSort(faSortArray,fSortOrder)
{
if ((faSortArray.constructor.name != "Array") || (fSortOrder.constructor.name != "String"))
{
alert ("Invalid constructor");
return;
}
var swapped, temp;
do
{
swapped = false;
for (var i=0; i < faSortArray.length-1; i++)
{
if (CompareString(faSortArray[i],faSortArray[i+1],fSortOrder) == 1)
{
temp = faSortArray[i];
faSortArray[i] = faSortArray[i+1];
faSortArray[i+1] = temp;
swapped = true;
}
}
} while (swapped);
return faSortArray;
}
function CompareString(String1,String2,fSortOrder)
{
var result = 0;
for (var i = 0; i <= String1.length;i++)
if (String1.charAt(i) != String2.charAt(i))
{
var PosInString1 = fSortOrder.indexOf(String1.charAt(i));
var PosInString2 = fSortOrder.indexOf(String2.charAt(i));
if (PosInString1 > PosInString2)
{
result = 1;
}
else
{
result = 2;
}
break;
}
return result;
}
Copy link to clipboard
Copied
Klaus,
I really have a problem with your code (which BTW works correctly):
The for loop in CompareString has no opening brace. What is its scope?
That is, If I add that missing opening brace, on which line I need to insert the closing brace?
I have never seen a loop without a block - { ...}
Copy link to clipboard
Copied
A loop executes the next command or a group of commands enclosed in brace.
If you only use one command, braces are not mandatory.
And the whole "if...." construction is only one "command". So its not looking good, but it works.
Copy link to clipboard
Copied
Thanks for the explanation, Klaus. I knew that for if statements, but for loops it is absolutely new for me ...
I'm an old-school programmer - started with Fortran in the '60ies and for long time we did not have reasonable structural facility. Only with a pre-compiler we got the { ... } constructs for a clearer program.
Remember Dijkstra (Edsger W.): GoTo considered harmful - it took us a while to abandon those habits and hence I'm sworn to the {...}