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: The information on this website is provided without warranty and any content is merely the opinion of the author. Please try to test in development environments prior to adapting them to your production environments. The articles are written in good faith and, at the time of print, are working examples used 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 - Valid till 8 May 2022 3QnhmaBX7LQSRsC9hh6Je9rGQKEGNQNfPb
© 2021 Joel Lipman .com. All Rights Reserved.