Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Array Sorting? 2

Status
Not open for further replies.

ChrisQuick

Programmer
Oct 4, 1999
144
US
Assuming that have an array with last name, age and city for 3 people in this order:

'SMITH','30','ATLANTA'
'JONES','28','LAS VEGAS'
'ADAMS','40',''ORLANDO'

and I wanted to sort based on the city name, how would I do this? Would it be possible to write a function to sort an array using the convention:

someNewfunction(arrayName,sortColumn)??

Any thoughts? cquick@geotg.com
Geographic Information System (GIS), ASP, some Oracle
 
What exactly do you mean by sort? Are you meaning make an array which has City as the first entry? That would be very straight forward (famous last words) I think, but this is probably not what you mean right? ;-)
b2 - benbiddington@surf4nix.com
 
No, I mean that I could sort by the first element to produce:
'ADAMS','40','ORLANDO'
'JONES','28','LAS VEGAS'
'SMITH','30','ATLANTA'

Sorting by the second would produce:
'JONES','28','LAS VEGAS'
'SMITH','30','ATLANTA'
'ADAMS','40','ORLANDO'

and sorting by the third:
'SMITH','30','ATLANTA'
'JONES','28','LAS VEGAS'
'ADAMS','40','ORLANDO'





cquick@geotg.com
Geographic Information System (GIS), ASP, some Oracle
 
The Array object has a sort method. Excuse the long post but here's what I have on the method ...

---------------------------------------------------------
The sort method sorts the elements of an array. If no compareFunction argument is supplied, all the elements are converted into strings and sorted lexicographically (i.e. in dictionary order). This means, for example, that 30 would come before 4. The following example is a straight-forward sort of an array of names:

Code:
names = ["John", "Andrea", "Charlie", "Sam", "Kate"]
sorted_names = names.sort()
document.write(sorted_names)

Output:
Andrea,Charlie,John,Kate,Sam

By including a compareFunction argument, you can define the sort order. Two array elements are sorted according to the return value of the compare function: if it is 0, the order of the two elements remains unchanged; if it is greater than 0, the first of the two elements is sorted to a higher index than the second; and if it is less than 0, the second element is sorted to a higher index than the first. The following code creates an array called 'trees' and then, using the user-defined function 'reverseSort', displays the elements sorted in reverse order:

Code:
trees = ["oak", "ash", "beech", "maple", "sycamore"]
function reverseSort(a, b)
{
if(a > b)
return -1
if(a < b)
return 1
return 0
}
document.write(trees.sort(reverseSort))

Output:
sycamore,oak,maple,beech,ash

If two numbers are compared, the compareFunction simply needs to subtract the second from the first number:

Code:
ages = [30, 25, 47, 19, 21, 8]
function sortNumbers(a, b) { return a - b}
document.write(ages.sort(sortNumbers))

Output:
8,19,21,25,30,47

---------------------------------------------------------

Greg.
 
But how would you tell it to sort by the 2nd or third column(if that's the right word) in an array? cquick@geotg.com
Geographic Information System (GIS), ASP, some Oracle
 
Well, perhaps you could try a multidimensional array - so the array you have contains arrays of information. Each one in your example would contain: [name,age,city] - and you have as mnay of these inside your bigger array - so to accesss the first entrant's name you would use:

names[0][0]

their city

names[0][2]

assuming your holding array is called names. Now the sort method really treats the array like a vector - strictly one dimension - and just sorts like that - so you want to write a function which takes one of the items from each persons details and uses that to sort, then remembers the order, and sorts the whole list - this is the idea, ubnested ofcourse ;-)
b2 - benbiddington@surf4nix.com
 
See if you can make some sense of this, sorry about the bad comments. Just cut and paste, you'll see it does what you wanted, but I think it could be streamlined a little.
I have created a new type of arrray - which extends Array, by having one additional field, which keeps an index for us to access information from it later - have a look anyway, and see if you can use it.


<html>
<head>
<title>Untitled</title>
<STYLE type=&quot;text/css&quot;>
BODY {font-size:10pt;font-family:Tahoma}
code {font-family:Courier new;background-color:cornsilk;padding:15;display:block;
text-align:left;margin:5;padding-left:20;font-size:8pt;margin-bottom:10}
.btn_black {background-color:black;color:silver;font-family:Arial,Verdana}
H3 {margin-left:20}
</STYLE>
<script>
// This constructor takes an integer argument, which is it's arbitrary
// initial position within the bigger array, so it knows where it is
// and we can change how they are sorted.
// The memoryVector contains all the information about the person, and we access it thru
// it's internal content array.
function memoryVector(){
this.index = arguments[0];
this.content = new Array();
for(i=1;i<arguments.length;i++){
this.content[i-1] = arguments;
}

}
// Array of memory capable vectors, which can reorganize themselves into a different
// order, depending on sorting.
var people = new Array();
people[0] = new memoryVector(0,&quot;Ben&quot;,&quot;22&quot;,&quot;Blenheim&quot;);
people[1] = new memoryVector(1,&quot;Chris&quot;,&quot;26&quot;,&quot;France&quot;);
people[2] = new memoryVector(2,&quot;Alan&quot;,&quot;28&quot;,&quot;Wellington&quot;);
people[3] = new memoryVector(3,&quot;Gus&quot;,&quot;17&quot;,&quot;Dunedin&quot;);
people[4] = new memoryVector(4,&quot;Dice&quot;,&quot;44&quot;,&quot;Las-Vegas&quot;);
people[5] = new memoryVector(5,&quot;Goofs&quot;,&quot;33&quot;,&quot;Naseby&quot;);

// This function needs to be given the array to sort, and the integer corresponding to
// the entry we a re going to sort by.
// It will go thru each vector inside the array, and pick out which we are going to sort by
// e.g. City - picks out all the cities, and sorts.
function sort(array,Vector_index){
//sort by whichever index specified
var oldIndices = new Array();
var sortKeys = new Array();
for(var i = 0;i<array.length;i++){
oldIndices = new Array(array.index,array.content[Vector_index]); //pick the city out
sortKeys = array.content[Vector_index];
}
sortKeys.sort();

// Now we have sorted the arrays, we want to put them in their array
// in the order specified by the sort. So we are going to reset the vector's
// index property. Need to get the position in the new array 'cities'.
var sortedArray = new Array();
for(var i=0;i<sortKeys.length;i++){
// match entry in sortKeys to one in oldIndices, and get the index
var matchingIndex = matchToArray(sortKeys,oldIndices);
sortedArray = array[matchingIndex];
}
var sortedString =&quot;<br>This is the array sorted:<br>&quot;;
for(var i=0;i<sortedArray.length;i++){
sortedString += &quot;<br>&quot;+ sortedArray.content.toString();
}
sortedOut(sortedString);
}
// This function takes something - matches it to an entry in the array - and returns
// another value from it - in this case the index it has in the original array.
function matchToArray(matchThis,matchingArray){
var match;
for(var j=0;j<matchingArray.length;j++){
if(matchingArray[j][1].indexOf(matchThis)!=-1){
match = matchingArray[j][0];
}
}
return match;
}


function sortedOut(message){
var status = document.getElementById(&quot;sortedOutput&quot;);
status.innerHTML= message;
}

</script>
</head>

<body>

<FORM>
<input type=&quot;button&quot; value=&quot;Sort by Name&quot; class=&quot;btn_black&quot; onClick=&quot;sort(people,0)&quot;>
<input type=&quot;button&quot; value=&quot;Sort by Location&quot; class=&quot;btn_black&quot; onClick=&quot;sort(people,2)&quot;>
<input type=&quot;button&quot; value=&quot;Sort by Age&quot; class=&quot;btn_black&quot; onClick=&quot;sort(people,1)&quot;><br>

</FORM>

<span id ='output'>

</span>
<span id ='sortedOutput'>

</span>

</body>
</html>
;-)
b2 - benbiddington@surf4nix.com
 
Actually, here is a better function - takes an array, and the column to sort by, and returns sorted Array. You could add another argument for the sorting option if you wanted too.

function sort_V2(array,sort_index){
var sortKey = new Array();
var sortedArray = new Array();
// get the sortKey, based on the index given
for(var i=0;i<array.length;i++){
sortKey = array[sort_index];
}
// sort them - add sorting option here
sortKey.sort();

// Go thru the sortKey - one at a time filling sortedArray
for(var i=0;i<sortKey.length;i++){

for(var j=0;j<array.length;j++){

if(array[j][sort_index].indexOf(sortKey) != -1){
// Then we have a match
// go and get the full array entry
sortedArray = array[j];
}
}
}
return sortedArray;
}
b2 - benbiddington@surf4nix.com
 
Well, this final draft deals with possibility o duplicate entries - people with the same name etc. The last code would overwrite all those with a matching entry with the first instance it came across - so the first instance of a repeated name in the array - would be copied into the sorted array for each other person with the same name.
These two functions stop this happening.

function sort_V3(array,sort_index){
var sortKey = new Array();
var sortedArray = new Array();
// get the sortKey, based on the index given
for(var i=0;i<array.length;i++){
sortKey = array[sort_index];
}
// sort them
sortKey.sort();

// Go thru the sortKey - one at a time filling sortedArray
for(var i=0;i<sortKey.length;i++){

for(var j=0;j<array.length;j++){
matching:
if(array[j][sort_index].indexOf(sortKey) != -1){
// Then we have a match
var checkVector = array[j];
var duplicateEntry = checkForDuplicate(checkVector,sortedArray);
if(i==0){sortedArray = checkVector;}
else if(!duplicateEntry){
sortedArray = checkVector;
}
else{break matching;}
}// end if
}

}
return sortedArray;

}

function checkForDuplicate(key,arrayToCheck){
var duplicate = 0;
for(var i=0;i<arrayToCheck.length;i++){
if(arrayToCheck.toString().indexOf(key) != -1){
duplicate = 1;
break;
}
else{}
}
return duplicate;
}
b2 - benbiddington@surf4nix.com
 
Thanks Bangers!! cquick@geotg.com
Geographic Information System (GIS), ASP, some Oracle
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top