loading...
Cover image for A Quick Review of JavaScript’s Array.prototype.sort() Method

A Quick Review of JavaScript’s Array.prototype.sort() Method

isalevine profile image Isa Levine Updated on ・5 min read

Junior JavaScript Jobhunting: Quick Tips for Technicals and Takehomes (5 Part Series)

1) Learning JavaScript Testing Quickly with Mocha, Chai, and Sinon (and a Lot of Gaps) 2) Passing Command-Line Arguments in Node.js 3) Three Ways to Retrieve JSON from the Web using Node.js 4) A Quick Review of JavaScript’s Array.prototype.sort() Method 5) Parsing CSV Files in Node.js with fs.createReadStream() and csv-parser

Cover image credit: Hunter x Hunter manga by Yoshihiro Togashi, meme-ified by yours truly. <3

In interviews, it is essential to know the basics of a language you choose to use. It sounds like common sense, but gaps in basic knowledge can make you look bad. After an (ahem) unflattering experience involving skimming the MDN documents on JavaScript’s Array.protoype.sort() method a little too quickly, I wanted to break down a simple implementation using the same JSON object we retrieved earlier in this series.

gif of hisoka holding out a hand of playing cards, some of them facing the wrong direction
Sorting things is important! Just ask this guy, he clearly knows what he's doing!

Default Array.protoype.sort() Behavior

By default, calling .sort() on a JavaScript array will attempt some basic lowest-to-highest ordering, based on either a string’s alphabetical order or a number’s value. However, the default behavior will compare only the FIRST ELEMENT of the string (first letter only) or number (first digit encountered).

Here are the examples of each from the MDN docs:

// sorting strings alphabetically, based on the first letter
var months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"]

// sorting integers by their first digit
var array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]

Understandably, you may be caught off-guard by seeing 100000 come between 1 and 21. Luckily, JavaScript gives us a built-in way to customize our sorting behavior using a compareFunction inside .sort()!

Defining Sorting Behavior with a compareFunction, .sort( function(a, b) { … } )

We can change the default sorting behavior by adding an anonymous function, called the compareFunction. We add this inside the .sort() call, and pass arguments a and b to represent the Array’s elements.

For example, instead of comparing only the first digit of integers, we can compare the entire value of a and b and sort based on that.

Adapted again from the MDN docs:

// sorting integers by their value
var array1 = [1, 30, 4, 21, 100000];

array1.sort(function(a, b) {   // this anonymous function is the compareFunction
    if (a < b) {    // now the entire values of a & b are compared
        return -1;
    };
    if (a > b) {
        return 1;
    };
    // a must be equal to b, no change to index
    return 0;
});

console.log(array1);
// expected output: Array [1, 4, 21, 30, 100000]

Great! Now, by explicitly comparing the entire values of a and b, instead of just their first digit, we get the numeric sorting we'd expect.

Note that the anonymous compareFunction is special, because it is looking for a return that is negative(-1), zero(0), or positive(1):

Negative  =>  lower index
Zero      =>  no change
Positive  =>  higher index

Thus, we can create any conditionals we want to ultimately return a negative/zero/positive value.

Sorting JSON Based on Nested Properties

TL;DR: Assign your nested properties to variables you can easily use in your comparison logic!

Let’s look at a more complicated example: sorting the JSON from https://www.reddit.com/r/popular.json alphabetically by their "title" property.

As a reminder, here’s the JSON we’ll be sorting, specifically based on properties inside the data.children Array:

sorted json from reddit's /r/popular board

We’ll use the same node-fetch package explored in the previous post in this series:

const url = "https://www.reddit.com/r/popular.json"


// use the node-fetch package to retrieve JSON from the URL above
const fetch = require('node-fetch');


let settings = {
    method: "Get"
};

fetch(url, settings)
.then(res => res.json())
.then((json) => {
    sortJson(json);
});

Inside our sortJson() function, we’ll use the following steps:

  1. We select a property to read inside each Object inside the data.children Array, accessed via data.children[i].data[property].
  2. We define a compareFunction that compares the properties of a and b, using our defined ”property”. We assign the nested values to easily accessible variables, property1 and property2.

  3. Compare property1 and property2. As usual, these comparisons return a negative(-1), zero(0), or positive(1) value. The original Array will be re-ordered based on the property.




Here’s our function, sorting by upvotes using the ”title” property:

// sort Array json.data.children alphabetically by "title"
function sortJson(json) {

    // you can easily change this to any property, such as “ups” or “author_fullname"
    let property = "title";  


    json.data.children.sort(function(a, b) {

        // create new variables to easily access nested data for sorting
        let property1 = a.data[property];
        let property2 = b.data[property];

        if (property1 < property2) {    // checks for a “lower” alphabetical order
            return -1
        };
        if (property1 > property2) {    // checks for a “higher” alphabetical order
            return 1
        };
        return 0    // if titles are equal

    });


// First 3 Objects in Array json.data.children BEFORE sort():
// [0].data.title: What do you NEVER f*** with?
// [1].data.title: [Game Thread] Florida vs. Miami (7:00PM ET)
// [2].data.title: 🎉 100.000.000 SUBSCRIBERS 🎉

// First 3 Objects in Array json.data.children AFTER sort():
// [0].data.title: 'Like you've been fired from your job': YouTubers have lost thousands of dollars after their channels were mistakenly demonetized for months
// [1].data.title: Disney+ episodes will release on a weekly basis, instead of the all at once “binge” model
// [2].data.title: Employee spits in food for Instagram likes

Note in our output that normal JavaScript string alphabetizing rules apply, such as the apostrophe ' coming before the letter D.

Conclusion

Sorting is an essential function in any language, so make sure to practice it before going into a technical challenge! Additionally, for languages like JavaScript and Ruby, make sure to dig into how sorting methods are implemented under-the-hood, as you may be asked to create some customized sorting functionality.

And, as usual, it won't hurt to take some time and familiarize yourself with the MDN docs, in case you need them for quick reference: MDN docs for Array.protoype.sort()

Feel free to comment below with any additional sorting tips or tricks!

UPDATE 8/28/19

Phil Nash just posted an INCREDIBLE writeup of gotchas and inconsistencies in JavaScript's Array.prototype.sort(). Specifically, he covers a two important topics that are complementary to this review:

  • How nulls are handled (coerced into either string "null" or integer 0)
  • How undefineds/objects with undefined values are handled

Check out his article here!

Junior JavaScript Jobhunting: Quick Tips for Technicals and Takehomes (5 Part Series)

1) Learning JavaScript Testing Quickly with Mocha, Chai, and Sinon (and a Lot of Gaps) 2) Passing Command-Line Arguments in Node.js 3) Three Ways to Retrieve JSON from the Web using Node.js 4) A Quick Review of JavaScript’s Array.prototype.sort() Method 5) Parsing CSV Files in Node.js with fs.createReadStream() and csv-parser

Posted on by:

isalevine profile

Isa Levine

@isalevine

Isa (ee-suh). She/her pronouns. Full stack developer working with Rails and Vue. Drinks too much bubbly water.

Discussion

markdown guide