An article on how to quickly adapt an array code and sort by its values. Surprising how many examples are on the web and everyone saying you're doing it wrong... Which is true but quite unhelpful. The original code is not my own either but that's not an excuse. I also found that examples across the web were only partial and thought I'd write a full example here. No jQuery and using the Google Chrome browser. I wanted to:
- Sort the array by its values
- Iterate through and output these in HTML
What I have:
copyraw
What I want:var my_records = new Array(); my_records["item1"] = "My Value 2"; my_records["item2"] = "My Value 3"; my_records["item3"] = "My Value 1"; document.write('<option value="item1">My Value 2</option>'); document.write('<option value="item2">My Value 3</option>'); document.write('<option value="item3">My Value 1</option>');
- var my_records = new Array();
- my_records["item1"] = "My Value 2";
- my_records["item2"] = "My Value 3";
- my_records["item3"] = "My Value 1";
- document.write('<option value="item1">My Value 2</option>');
- document.write('<option value="item2">My Value 3</option>');
- document.write('<option value="item3">My Value 1</option>');
copyraw
var my_records = new Array(); my_records["item3"] = "My Value 1"; my_records["item1"] = "My Value 2"; my_records["item2"] = "My Value 3"; document.write('<option value="item3">My Value 1</option>'); document.write('<option value="item1">My Value 2</option>'); document.write('<option value="item2">My Value 3</option>');
- var my_records = new Array();
- my_records["item3"] = "My Value 1";
- my_records["item1"] = "My Value 2";
- my_records["item2"] = "My Value 3";
- document.write('<option value="item3">My Value 1</option>');
- document.write('<option value="item1">My Value 2</option>');
- document.write('<option value="item2">My Value 3</option>');
Why?
I could give my client a condescending lesson on the semantics of javascript 'associative arrays' and just say it's not possible, they should get their datasource ordered... Or I can say 'Of course it's possible!' and just tweak their code ever so slightly.
How?
A lot of examples out there use numbers which makes the task easier. I'm the type of idiot that volunteers first and asks for details afterwards. I get the task to sort by string values.
Note: This has been adapted to work when using the Google Chrome browser (at time of print: Version 45.0.2454.101 m).
Method #1: Convert to JSON then split string
Changing as little as possible to the customer's code, we need to find&replace their datasource code:
copyraw
// replace 'new Array();' with "[" // open square bracket // replace 'my_records["' with "{ myKey: '" // replace '"] = "' with "', myValue: '" // replace '";' with "' }," // omit comma for the last element // yielding: var my_records = [ { myKey: 'item1', myValue: 'My Value 2' }, { myKey: 'item2', myValue: 'My Value 3' }, { myKey: 'item3', myValue: 'My Value 1' } ] // make copy of my_records array/object var my_records_copy = my_records.slice(0); // sorts the array by myValue (string) my_records_copy.sort(function(a,b) { var x = a.myValue.toLowerCase(); var y = b.myValue.toLowerCase(); return x < y ? -1 : x > y ? 1 : 0; }); // use built-in JSON stringify function newSortedArrayObject = JSON.stringify(my_records_copy); // note: will convert single apostrophes to double-quotes // split by closing curly brace var myRecords = newSortedArrayObject.split('}'); // removes last row which is undefined (ie. "]") myRecords.pop(); // loop through array for (i=0; i<myRecords.length; i++){ // split the record where double-quote is the delimiter var thisRecord = myRecords[i].split('"'); // output document.write('<option value="' + thisRecord[3] + '">' + thisRecord[7] + '</option>'); }
- // replace 'new Array();' with "[" // open square bracket
- // replace 'my_records["' with "{ myKey: '"
- // replace '"] = "' with "', myValue: '"
- // replace '";' with "' }," // omit comma for the last element
- // yielding:
- var my_records = [
- { myKey: 'item1', myValue: 'My Value 2' },
- { myKey: 'item2', myValue: 'My Value 3' },
- { myKey: 'item3', myValue: 'My Value 1' }
- ]
- // make copy of my_records array/object
- var my_records_copy = my_records.slice(0);
- // sorts the array by myValue (string)
- my_records_copy.sort(function(a,b) {
- var x = a.myValue.toLowerCase();
- var y = b.myValue.toLowerCase();
- return x < y ? -1 : x > y ? 1 : 0;
- });
- // use built-in JSON stringify function
- newSortedArrayObject = JSON.stringify(my_records_copy);  // note: will convert single apostrophes to double-quotes
- // split by closing curly brace
- var myRecords = newSortedArrayObject.split('}');
- // removes last row which is undefined (ie. "]")
- myRecords.pop();
- // loop through array
- for (i=0; i<myRecords.length; i++){
- // split the record where double-quote is the delimiter
- var thisRecord = myRecords[i].split('"');
- // output
- document.write('<option value="' + thisRecord[3] + '">' + thisRecord[7] + '</option>');
- }
Other Methods?
Bearing in mind that I needed to sort by the values and then output in HTML format using Google Chrome, the above is the only method I could actually get working, and leave it in an understandable manner for my customers. Other sources I browsed before working out this solution:
- Stack Overflow: How to sort an associative array by its values in Javascript
- Sort array of objects by string property value in JavaScript
- Stack Overflow: Sorting JSON by Values
- iFadey: Sort Javascript Object by Key or Value
- Mozilla.org: Array.prototype.sort()
Category: JavaScript :: Article: 632
Add comment