15 Killer 🗡 JS techniques you've probably never heard of 🔈🔥
Tags: javascript, programming, tutorial, beginners
Published: 2023-02-16 13:19:24

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.

```js
const arr = ["a", "b", "c", "d", "d", "c", "e"]
const uniqueArray = Array.from(new Set(arr));

console.log(uniqueArray); // ['a', 'b', 'c', 'd', 'e']
```

{% details Explanation %} 
[MDN Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
{% enddetails %}

### 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.

```js
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](https://dev.to/jonrandy/comment/24ojn).

{% details Explanation %} 
[MDN Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)

[Stackoverflow Solution](https://stackoverflow.com/questions/41404607/why-does-javascript-set-not-do-unique-objects)
{% enddetails %}

### Array Iterator Index
With the `.map` and `.forEach` javascript iteration functions, you can get the index of each item.

```js
const arr = ['a', 'b', 'c'];
const letterPositions = arr.map(
  (char, index) => `${char} is at index ${index}`
)
```

{% details Explanation %} 
[Array.prototype.map (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

[Array.prototype.forEach (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
{% enddetails %}

### Split string by # of chars
We can use the `.match` regular expression function to split a string by `n` characters.

```js
const str = "asdfghjklmnopq";
const splitPairs = str.match(/.{1,2}/g);

console.log(splitPairs); // ['as', 'df', 'gh', 'jk', 'lm', 'no', 'pq']
```

{% details 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.

Alternatively, if you want to split a string by `n` characters where `n` is subject to change, you can do it with `new RegExp`.

```js
const splitPairsBy = (n) => str.match(new RegExp(`.{1,${n}}`, "g"))
```

[String.prototype.match (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)

[Stackoverflow Solution](https://stackoverflow.com/questions/6259515/how-can-i-split-a-string-into-segments-of-n-characters)
{% enddetails %}

### Split string by different chars
Another regex hack with `.match` allows you to split a string like "aabbc" to an array `["aa", "bb", "c"]`.

```js
const str = "abbcccdeefghhiijklll";
const splitChars = str.match(/(.)\1*/g);

console.log(splitChars); // ['a', 'bb', 'ccc', 'd', 'ee', 'f', 'g', 'hh', 'ii', 'j', 'k', 'lll']
```

{% details Explanation %} 
[String.prototype.match (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)

[Stackoverflow Solution](https://stackoverflow.com/questions/21997437/javascript-split-string-by-multiple-occurrences-of-letters)
{% enddetails %}

### 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.

```js
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']
```

{% details Explanation %} 
If `obj` is passed through `Object.entries`, it will look something like this:

```json
[
  ["key1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"]
]
```

Using the `.map` function alongside object destructuring lets us access the key-values.

[Object.entries (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)
{% enddetails %}

### Key-Value Array to Object
You can convert an "`Object.entryified`" array of key-values back to an object with `Object.fromEntries`

```js
const entryified = [
  ["key1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"]
];

const originalObject = Object.fromEntries(entryified);

console.log(originalObject); // { key1: 'value1', ... }
```

{% details Explanation %} 
[Object.fromEntries (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)
{% enddetails %}

### 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.

```js
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](https://dev.to/jonrandy/comment/24ojn)!

{% details Explanation %} 
[Array.prototype.filter (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
{% enddetails %}

### 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.

```js
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
```

{% details Explanation %} 
[String.prototype.replace (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace)
{% enddetails %}

### 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.

```js
const obj = {
  "a": "aaaaaaa",
  "b": null
};

console.log(obj.b.d); // throws an error

console.log(obj.b?.d); // returns undefined
```

{% details Explanation %} 
[Optional Chaining (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
{% enddetails %}

### 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.

```js
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:

```js
const constrain = (num, min, max) => Math.min(Math.max(num, min), max)
```

Thanks @jonrandy 🙏

{% details Explanation %} 
[If-else (MDN) 🤪](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
{% enddetails %}

### 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.

```js
const arr = [1, 2, 3, 4, 5];

arr.at(0) // 1
arr.at(1) // 2
arr.at(-1) // 5
arr.at(-2) // 4
```

{% details Explanation %} 
[Array.prototype.at (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at)
{% enddetails %}

### Sort alphabetically
Sort an array of strings alphabetically

```js
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)`

{% details Explanation %} 
[Array.prototype.sort (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
{% enddetails %}

### 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.

```js
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.

{% details Explanation %} 
[Array.prototype.sort (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)

[Number (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)
{% enddetails %}

### 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.

```js
console.log(Math.PI); // 3.141592653589793
console.log(Number(Math.PI.toFixed(2)))
```

{% details Explanation %} 
[Number.prototype.toFixed (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed)
{% enddetails %}

---

Thanks for reading ✨!  

I'm open to feedback.  If you have any thoughts or comments be sure to share them in the comments below.

# Let's talk 👋
 - 🐱 [Github](https://github.com/Conner1115)
 - 🦜 [Twitter](https://twitter.com/IroncladDev)
 - ⠕ [Replit](https://replit.com/@IroncladDev)
 - 🌐 [Website](https://www.connerow.dev)
 - ✉️ [Email](mailto:connerow1115@gmail.com)