Sort an associative array by values in Javascript

What?
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:
  1. Sort the array by its values
    copyraw
    my_records.sort();
    1.  my_records.sort()
  2. Iterate through and output these in HTML
    copyraw
    for(i=0;i<my_records.length;i++){
            // do something to my_records[i]
    }
    1.  for(i=0;i<my_records.length;i++){ 
    2.          // do something to my_records[i] 
    3.  } 

What I have:
copyraw
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>');
  1.  var my_records = new Array()
  2.          my_records["item1"] = "My Value 2"
  3.          my_records["item2"] = "My Value 3"
  4.          my_records["item3"] = "My Value 1"
  5.   
  6.          document.write('<option value="item1">My Value 2</option>')
  7.          document.write('<option value="item2">My Value 3</option>')
  8.          document.write('<option value="item3">My Value 1</option>')
What I want:
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>');
  1.  var my_records = new Array()
  2.          my_records["item3"] = "My Value 1"
  3.          my_records["item1"] = "My Value 2"
  4.          my_records["item2"] = "My Value 3"
  5.   
  6.          document.write('<option value="item3">My Value 1</option>')
  7.          document.write('<option value="item1">My Value 2</option>')
  8.          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>');
        }
  1.  // replace 'new Array();'       with "["                // open square bracket 
  2.          // replace 'my_records["'       with "{ myKey: '" 
  3.          // replace '"] = "'             with "', myValue: '" 
  4.          // replace '";'                 with "' },"             // omit comma for the last element 
  5.   
  6.          // yielding: 
  7.          var my_records = [ 
  8.                  { myKey: 'item1', myValue: 'My Value 2' }, 
  9.                  { myKey: 'item2', myValue: 'My Value 3' }, 
  10.                  { myKey: 'item3', myValue: 'My Value 1' } 
  11.          ] 
  12.   
  13.          // make copy of my_records array/object 
  14.          var my_records_copy = my_records.slice(0)
  15.   
  16.          // sorts the array by myValue (string) 
  17.          my_records_copy.sort(function(a,b) { 
  18.                  var x = a.myValue.toLowerCase()
  19.                  var y = b.myValue.toLowerCase()
  20.                  return < y ? -1 : x > y ? 1 : 0
  21.          })
  22.   
  23.          // use built-in JSON stringify function 
  24.          newSortedArrayObject = JSON.stringify(my_records_copy);  // note: will convert single apostrophes to double-quotes 
  25.   
  26.          // split by closing curly brace 
  27.          var myRecords = newSortedArrayObject.split('}')
  28.   
  29.          // removes last row which is undefined (ie. "]") 
  30.          myRecords.pop()
  31.   
  32.          // loop through array 
  33.          for (i=0; i<myRecords.length; i++){ 
  34.   
  35.                  // split the record where double-quote is the delimiter 
  36.                  var thisRecord = myRecords[i].split('"')
  37.   
  38.                  // output 
  39.                  document.write('<option value="' + thisRecord[3] + '">' + thisRecord[7] + '</option>')
  40.          } 

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:
Category: JavaScript :: Article: 632

Credit where Credit is Due:


Feel free to copy, redistribute and share this information. All that we ask is that you attribute credit and possibly even a link back to this website as it really helps in our search engine rankings.

Disclaimer: Please note that the information provided on this website is intended for informational purposes only and does not represent a warranty. The opinions expressed are those of the author only. We recommend testing any solutions in a development environment before implementing them in production. The articles are based on our good faith efforts and were current at the time of writing, reflecting our practical experience in a commercial setting.

Thank you for visiting and, as always, we hope this website was of some use to you!

Kind Regards,

Joel Lipman
www.joellipman.com

Related Articles

Joes Revolver Map

Accreditation

Badge - Certified Zoho Creator Associate
Badge - Certified Zoho Creator Associate

Donate & Support

If you like my content, and would like to support this sharing site, feel free to donate using a method below:

Paypal:
Donate to Joel Lipman via PayPal

Bitcoin:
Donate to Joel Lipman with Bitcoin bc1qf6elrdxc968h0k673l2djc9wrpazhqtxw8qqp4

Ethereum:
Donate to Joel Lipman with Ethereum 0xb038962F3809b425D661EF5D22294Cf45E02FebF
© 2024 Joel Lipman .com. All Rights Reserved.