We can all agree that searching for a Javascript bug fix or answer on Google or StackOverflow is not fun π΄ββ οΈ.
Here are twenty short and powerful JavaScript techniques that will maximize productivity β‘οΈ and minimize pain π©Έ.
Let's dive into the code π€
Unique Array
Filter out duplicate values from an Array.
const arr = ["a", "b", "c", "d", "d", "c", "e"]
const uniqueArray = Array.from(new Set(arr));
console.log(uniqueArray); // ['a', 'b', 'c', 'd', 'e']
Unique Array of Objects
The Set object won't allow you to filter out duplicate objects since each one is different. JSON.stringify does the trick for us here.
const arr = [{ key: 'value' }, { key2: 'value2' }, { key: 'value' }, { key3: 'value3' }];
const uniqueObjects = Array.from(
new Set(
arr.map(JSON.stringify)
)
).map(JSON.parse)
console.log(uniqueObjects);
See a more efficient but slightly longer method in this comment.
Array Iterator Index
With the .map and .forEach javascript iteration functions, you can get the index of each item.
const arr = ['a', 'b', 'c'];
const letterPositions = arr.map(
(char, index) => `${char} is at index ${index}`
)
Split string by # of chars
We can use the .match regular expression function to split a string by n characters.
const str = "asdfghjklmnopq";
const splitPairs = str.match(/.{1,2}/g);
console.log(splitPairs); // ['as', 'df', 'gh', 'jk', 'lm', 'no', 'pq']
Alternatively, if you want to split a string by Explanation
In the regular expression /.{1,2}/g we used, the number 2 stands for how many characters we want to split by. If there is a remainder, this will still work.
n characters where n is subject to change, you can do it with new RegExp.
const splitPairsBy = (n) => str.match(new RegExp(`.{1,${n}}`, "g"))
Split string by different chars
Another regex hack with .match allows you to split a string like "aabbc" to an array ["aa", "bb", "c"].
const str = "abbcccdeefghhiijklll";
const splitChars = str.match(/(.)\1*/g);
console.log(splitChars); // ['a', 'bb', 'ccc', 'd', 'ee', 'f', 'g', 'hh', 'ii', 'j', 'k', 'lll']
Iterate through object
Object.entries allows us to turn a JSON object to an array of key-value pairs, thus enabling us to iterate through it with a loop or an array iterator.
const obj = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
};
const iteratedObject = Object.entries(obj)
.map(([key, value]) => `${key} = ${value}`);
console.log(iteratedObject); // ['key1 = value1', 'key2 = value2', 'key3 = value3']
Using the Explanation
If obj is passed through Object.entries, it will look something like this:
[
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
]
.map function alongside object destructuring lets us access the key-values.
Key-Value Array to Object
You can convert an "Object.entryified" array of key-values back to an object with Object.fromEntries
const entryified = [
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
];
const originalObject = Object.fromEntries(entryified);
console.log(originalObject); // { key1: 'value1', ... }
Occurrence Counting
You might want to count how many times an item appears in an array. We can use the .filter function with an iterator to accomplish this.
const occurrences = ["a", "b", "c", "c", "d", "a", "a", "e", "f", "e", "f", "g", "f", "f", "f"];
// creating a unique array to avoid counting the same char more than once
const unique = Array.from(new Set(occurrences));
const occurrenceCount = Object.fromEntries(
unique.map(char => {
const occurrenceCount = occurrences.filter(c => c === char).length;
return [char, occurrenceCount]
})
)
console.log(occurrenceCount); // { a: 3, b: 1, c: 2, ... }
Checkout a solid one-liner to do this in this comment!
Replacement Callback
The .replace function doesn't limit you to just replacing with a fixed string. You can pass a callback to it and use the matched substring.
const string = "a dog went to dig and dug a doggone large hole";
const replacedString = string.replace(/d.g/g, str => str + "gy")
console.log(replacedString); // a doggy went to diggy and duggy a doggygone large hole
Conditional chaining
Many of you are familiar with running into undefined errors in JS, conditional chaining can prevent a lot of that from happening.
The optional chaining (
?.) operator accesses an object's property or calls a function. If the object accessed or function called using this operator is undefined or null, the expression short circuits and evaluates to undefined instead of throwing an error.
const obj = {
"a": "aaaaaaa",
"b": null
};
console.log(obj.b.d); // throws an error
console.log(obj.b?.d); // returns undefined
Constrain a Number
Oftentimes you might need to contrain a number to be within a certain range. Doing it with the ternary operator every time you need it is a pain. A function is so much cleaner.
const constrain = (num, min, max) => {
if(num < min) return min;
else if(num > max) return max;
else return num;
}
constrain(5, 1, 3) // 3
constrain(2, 1, 5) // 2
constrain(0, -100, 100) // 0
A much better way to do it is with using Math.min and Math.max like this:
const constrain = (num, min, max) => Math.min(Math.max(num, min), max)
Thanks @jonrandy π
Indexing front and back of an array
The .at function allows you to index an array from the beginning and the end with positive and negative numbers.
const arr = [1, 2, 3, 4, 5];
arr.at(0) // 1
arr.at(1) // 2
arr.at(-1) // 5
arr.at(-2) // 4
Sort alphabetically
Sort an array of strings alphabetically
const words = ["javascript", "typescript", "python", "ruby", "swift", "go", "clojure"];
const sorted = words.sort((a, b) => a.localeCompare(b));
console.log(sorted); // ['clojure', 'go', 'javascript', 'python', 'ruby', 'swift', 'typescript']
π‘ Tip: You can switch the order between ascending and descending by switching a.localeCompare(b) to b.localeCompare(a)
Sort by Truthy/Falsy value
You can sort an array by a truthy/falsy value, placing those with the truthy value first and the falsy values after.
const users = [
{ "name": "john", "subscribed": false },
{ "name": "jane", "subscribed": true },
{ "name": "jean", "subscribed": false },
{ "name": "george", "subscribed": true },
{ "name": "jelly", "subscribed": true },
{ "name": "john", "subscribed": false }
];
const subscribedUsersFirst = users.sort((a, b) => Number(b.subscribed) - Number(a.subscribed))
Number(false) is equal to zero and Number(true) is equal to one. That's how we can pass it through the sort function.
Round Decimal to n digits
You can round a decimal to n digits with .toFixed. Note that .toFixed turns a number into a string, so we have to re-parse it as a number.
console.log(Math.PI); // 3.141592653589793
console.log(Number(Math.PI.toFixed(2)))
Thanks for reading β¨!
I'm open to feedback. If you have any thoughts or comments be sure to share them in the comments below.
Latest comments (53)
Great post!
Do you mind if I translate into Japanese, and post it to dev community in Japan?
Sure, as long as you link to the original post.
Thanks! Definitely.
Wasn't aware of the
Object.fromEntriesmethod, that's kind of useful! Certainly more succinct than iterating through a bunch of entries and extracting key values.I know the context is subjective but, to me, this is more "15 common JS techniques you use weekly" π
Good write-up though, definitly worth sharing with less experience front-enders!
How does the regular expression work? Representation of 2 was straightforward from the log. But what part of syntax is the g and the period? These look like special characters according to mdn, but how did you arrive to use those two characters?
Well
Cool! Some of them I had never heard of before.Β
Great article @ironcladdev
π© Red flag! I wouldn't trust the above code for general use.
Your Unique Array of Objects solution uses the incredibly expensive
JSON.stringifyandJSON.parseto do object comparison. While the code looks neat it is probably the least efficient way to go about it.A better approach would use _.isEqual for deep comparisons, or a concrete comparison on the significant fields, if not all fields are significant (which they rarely are --- e.g. an
idfield may imply the state of the other fields).As others have pointed out, your solution is not even correct.
I found this post via the "Top" posts page, which seems to be because it is getting a lot of engangement. I can't help but wonder whether your bad advice is intentional---to get engangement. You've gotten lots of feedback, but made no adjustments to the post.
The only thing these tips will kill is your app performance.
Great post.
Useful for beginners