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.
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:
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:
- We select a property to read inside each Object inside the
data.children
Array, accessed viadata.children[i].data[property]
. - We define a
compareFunction
that compares the properties ofa
andb
, using our defined”property”
. We assign the nested values to easily accessible variables,property1
andproperty2
. - Compare
property1
andproperty2
. 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 propertyA = a.data[property];
let propertyB = b.data[property];
if (propertyA < propertyB) { // checks for a “lower” alphabetical order
return -1
};
if (propertyA > propertyB) { // 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
Top comments (0)