-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1639 from bgoonz/master
- Loading branch information
Showing
104 changed files
with
12,467 additions
and
21,164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
title: Insert item inside an Array | ||
|
||
tip-number: 00 | ||
tip-username: loverajoel | ||
tip-username-profile: https://github.com/loverajoel | ||
tip-tldr: Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or to the middle using splice. | ||
tip-writer-support: https://www.coinbase.com/loverajoel | ||
|
||
- /en/insert-item-inside-an-array/ | ||
|
||
# Inserting an item into an existing array | ||
|
||
Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or to the middle using splice. | ||
|
||
Those are known methods, but it doesn't mean there isn't a more performant way. Here we go: | ||
|
||
## Adding an element at the end | ||
|
||
Adding an element at the end of the array is easy with push(), but it can be done in different ways. | ||
|
||
```javascript | ||
var arr = [1, 2, 3, 4, 5]; | ||
var arr2 = []; | ||
|
||
arr.push(6); | ||
arr[arr.length] = 6; | ||
arr2 = arr.concat([6]); | ||
``` | ||
|
||
Both first methods modify the original array. Don't believe me? Check the [jsperf](http://jsperf.com/push-item-inside-an-array) | ||
|
||
### Performance on mobile : | ||
|
||
#### Android (v4.2.2) | ||
|
||
1. _arr.push(6);_ and _arr[arr.length] = 6;_ have the same performance // 3 319 694 ops/sec | ||
2. _arr2 = arr.concat([6]);_ 50.61 % slower than the other two methods | ||
|
||
#### Chrome Mobile (v33.0.0) | ||
|
||
1. _arr[arr.length] = 6;_ // 6 125 975 ops/sec | ||
2. _arr.push(6);_ 66.74 % slower | ||
3. _arr2 = arr.concat([6]);_ 87.63 % slower | ||
|
||
#### Safari Mobile (v9) | ||
|
||
1. _arr[arr.length] = 6;_ // 7 452 898 ops/sec | ||
2. _arr.push(6);_ 40.19 % slower | ||
3. _arr2 = arr.concat([6]);_ 49.78 % slower | ||
|
||
```javascript | ||
Final victor | ||
|
||
1. arr[arr.length] = 6; // with an average of 5 632 856 ops/sec | ||
2. arr.push(6); // 35.64 % slower | ||
3. arr2 = arr.concat([6]); // 62.67 % slower | ||
``` | ||
|
||
### Performance on desktop | ||
|
||
#### Chrome (v48.0.2564) | ||
|
||
1. _arr[arr.length] = 6;_ // 21 602 722 ops/sec | ||
2. _arr.push(6);_ 61.94 % slower | ||
3. _arr2 = arr.concat([6]);_ 87.45 % slower | ||
|
||
#### Firefox (v44) | ||
|
||
1. _arr.push(6);_ // 56 032 805 ops/sec | ||
2. _arr[arr.length] = 6;_ 0.52 % slower | ||
3. _arr2 = arr.concat([6]);_ 87.36 % slower | ||
|
||
#### IE (v11) | ||
|
||
1. _arr[arr.length] = 6;_ // 67 197 046 ops/sec | ||
2. _arr.push(6);_ 39.61 % slower | ||
3. _arr2 = arr.concat([6]);_ 93.41 % slower | ||
|
||
#### Opera (v35.0.2066.68) | ||
|
||
1. _arr[arr.length] = 6;_ // 30 775 071 ops/sec | ||
2. _arr.push(6);_ 71.60 % slower | ||
3. _arr2 = arr.concat([6]);_ 83.70 % slower | ||
|
||
#### Safari (v9.0.3) | ||
|
||
1. _arr.push(6);_ // 42 670 978 ops/sec | ||
2. _arr[arr.length] = 6;_ 0.80 % slower | ||
3. _arr2 = arr.concat([6]);_ 76.07 % slower | ||
|
||
```javascript | ||
Final victor | ||
|
||
1. arr[arr.length] = 6; // with an average of 42 345 449 ops/sec | ||
2. arr.push(6); // 34.66 % slower | ||
3. arr2 = arr.concat([6]); // 85.79 % slower | ||
``` | ||
|
||
## Add an element at the beginning | ||
|
||
Now if we are trying to add an item to the beginning of the array: | ||
|
||
```javascript | ||
var arr = [1, 2, 3, 4, 5]; | ||
|
||
arr.unshift(0); | ||
[0].concat(arr); | ||
``` | ||
|
||
Here is a little more detail: unshift edits the original array; concat returns a new array. [jsperf](http://jsperf.com/unshift-item-inside-an-array) | ||
|
||
### Performance on mobile : | ||
|
||
#### Android (v4.2.2) | ||
|
||
1. _[0].concat(arr);_ // 1 808 717 ops/sec | ||
2. _arr.unshift(0);_ 97.85 % slower | ||
|
||
#### Chrome Mobile (v33.0.0) | ||
|
||
1. _[0].concat(arr);_ // 1 269 498 ops/sec | ||
2. _arr.unshift(0);_ 99.86 % slower | ||
|
||
#### Safari Mobile (v9) | ||
|
||
1. _arr.unshift(0);_ // 3 250 184 ops/sec | ||
2. _[0].concat(arr);_ 33.67 % slower | ||
|
||
```javascript | ||
Final victor | ||
|
||
1. [0].concat(arr); // with an average of 4 972 622 ops/sec | ||
2. arr.unshift(0); // 64.70 % slower | ||
``` | ||
|
||
### Performance on desktop | ||
|
||
#### Chrome (v48.0.2564) | ||
|
||
1. _[0].concat(arr);_ // 2 656 685 ops/sec | ||
2. _arr.unshift(0);_ 96.77 % slower | ||
|
||
#### Firefox (v44) | ||
|
||
1. _[0].concat(arr);_ // 8 039 759 ops/sec | ||
2. _arr.unshift(0);_ 99.72 % slower | ||
|
||
#### IE (v11) | ||
|
||
1. _[0].concat(arr);_ // 3 604 226 ops/sec | ||
2. _arr.unshift(0);_ 98.31 % slower | ||
|
||
#### Opera (v35.0.2066.68) | ||
|
||
1. _[0].concat(arr);_ // 4 102 128 ops/sec | ||
2. _arr.unshift(0);_ 97.44 % slower | ||
|
||
#### Safari (v9.0.3) | ||
|
||
1. _arr.unshift(0);_ // 12 356 477 ops/sec | ||
2. _[0].concat(arr);_ 15.17 % slower | ||
|
||
```javascript | ||
Final victor | ||
|
||
1. [0].concat(arr); // with an average of 6 032 573 ops/sec | ||
2. arr.unshift(0); // 78.65 % slower | ||
``` | ||
|
||
## Add an element in the middle | ||
|
||
Adding items in the middle of an array is easy with splice, and it's the most performant way to do it. | ||
|
||
```javascript | ||
var items = ['one', 'two', 'three', 'four']; | ||
items.splice(items.length / 2, 0, 'hello'); | ||
``` | ||
|
||
I tried to run these tests in various Browsers and OS and the results were similar. I hope these tips will be useful for you and encourage to perform your own tests! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
title: Improve Nested Conditionals | ||
tip-number: 03 | ||
tip-username: AlbertoFuente | ||
tip-username-profile: https://github.com/AlbertoFuente | ||
tip-tldr: How can we improve and make a more efficient nested `if` statement in javascript? | ||
|
||
- /en/improve-nested-conditionals/ | ||
|
||
How can we improve and make a more efficient nested `if` statement in javascript? | ||
|
||
```javascript | ||
if (color) { | ||
if (color === 'black') { | ||
printBlackBackground(); | ||
} else if (color === 'red') { | ||
printRedBackground(); | ||
} else if (color === 'blue') { | ||
printBlueBackground(); | ||
} else if (color === 'green') { | ||
printGreenBackground(); | ||
} else { | ||
printYellowBackground(); | ||
} | ||
} | ||
``` | ||
|
||
One way to improve the nested `if` statement would be using the `switch` statement. Although it is less verbose and is more ordered, it's not recommended to use it because it's so difficult to debug errors. Here's [why](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals). | ||
|
||
```javascript | ||
switch (color) { | ||
case 'black': | ||
printBlackBackground(); | ||
break; | ||
case 'red': | ||
printRedBackground(); | ||
break; | ||
case 'blue': | ||
printBlueBackground(); | ||
break; | ||
case 'green': | ||
printGreenBackground(); | ||
break; | ||
default: | ||
printYellowBackground(); | ||
} | ||
``` | ||
|
||
But what if we have a conditional with several checks in each statement? In this case, if we want it less verbose and more ordered, we can use the conditional `switch`. | ||
If we pass `true` as a parameter to the `switch` statement, it allows us to put a conditional in each case. | ||
|
||
```javascript | ||
switch (true) { | ||
case typeof color === 'string' && color === 'black': | ||
printBlackBackground(); | ||
break; | ||
case typeof color === 'string' && color === 'red': | ||
printRedBackground(); | ||
break; | ||
case typeof color === 'string' && color === 'blue': | ||
printBlueBackground(); | ||
break; | ||
case typeof color === 'string' && color === 'green': | ||
printGreenBackground(); | ||
break; | ||
case typeof color === 'string' && color === 'yellow': | ||
printYellowBackground(); | ||
break; | ||
} | ||
``` | ||
|
||
If refactoring is an option, we can try to simplify the functions themselves. For example instead of having a function for each background color we could have an function that takes the color as an argument. | ||
|
||
```javascript | ||
function printBackground(color) { | ||
if (!color || typeof color !== 'string') { | ||
return; // Invalid color, return immediately | ||
} | ||
} | ||
``` | ||
|
||
But if refactoring is not an option, we must always avoid having several checks in every condition and avoid using `switch` as much as possible. We also must take into account that the most efficient way to do this is through an `object`. | ||
|
||
```javascript | ||
var colorObj = { | ||
black: printBlackBackground, | ||
red: printRedBackground, | ||
blue: printBlueBackground, | ||
green: printGreenBackground, | ||
yellow: printYellowBackground | ||
}; | ||
|
||
if (color in colorObj) { | ||
colorObj[color](); | ||
} | ||
``` | ||
|
||
Here you can find more information about [this](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
title: Sorting strings with accented characters | ||
tip-number: 04 | ||
tip-username: loverajoel | ||
tip-username-profile: https://github.com/loverajoel | ||
tip-tldr: Javascript has a native method **sort** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. But when you try order an array of non ASCII characters you will obtain a strange result. | ||
tip-writer-support: https://www.coinbase.com/loverajoel | ||
|
||
- /en/sorting-strings-with-accented-characters/ | ||
|
||
Javascript has a native method **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. Also you can provide your [own custom sorting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. | ||
|
||
```javascript | ||
['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); | ||
// ["Buenos Aires", "Mumbai", "New York", "Shanghai"] | ||
``` | ||
|
||
But when you try order an array of non ASCII characters like this `['é', 'a', 'ú', 'c']`, you will obtain a strange result `['c', 'e', 'á', 'ú']`. That happens because sort works only with the English language. | ||
|
||
See the next example: | ||
|
||
```javascript | ||
// Spanish | ||
['único', 'árbol', 'cosas', 'fútbol'].sort(); | ||
// ["cosas", "fútbol", "árbol", "único"] // bad order | ||
|
||
// German | ||
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); | ||
// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order | ||
``` | ||
|
||
Fortunately, there are two ways to overcome this behavior [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) and [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) provided by ECMAScript Internationalization API. | ||
|
||
> Both methods have their own custom parameters in order to configure it to work adequately. | ||
### Using `localeCompare()` | ||
|
||
```javascript | ||
['único', 'árbol', 'cosas', 'fútbol'].sort(function (a, b) { | ||
return a.localeCompare(b); | ||
}); | ||
// ["árbol", "cosas", "fútbol", "único"] | ||
|
||
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) { | ||
return a.localeCompare(b); | ||
}); | ||
// ["Wann", "wäre", "Woche", "wöchentlich"] | ||
``` | ||
|
||
### Using `Intl.Collator()` | ||
|
||
```javascript | ||
['único', 'árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); | ||
// ["árbol", "cosas", "fútbol", "único"] | ||
|
||
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare); | ||
// ["Wann", "wäre", "Woche", "wöchentlich"] | ||
``` | ||
|
||
- For each method you can customize the location. | ||
- According to [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance) Intl.Collator is faster when comparing large numbers of strings. | ||
|
||
So when you are working with arrays of strings in a language other than English, remember to use this method to avoid unexpected sorting. |
43 changes: 43 additions & 0 deletions
43
docs/content/2016-01-05-differences-between-undefined-and.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
title: Differences between `undefined` and `null` | ||
tip-number: 05 | ||
tip-username: loverajoel | ||
tip-username-profile: https://github.com/loverajoel | ||
tip-tldr: Understanding the differences between `undefined` and `null`. | ||
tip-writer-support: https://www.coinbase.com/loverajoel | ||
|
||
- /en/differences-between-undefined-and-null/ | ||
|
||
- `undefined` means a variable has not been declared, or has been declared but has not yet been assigned a value | ||
- `null` is an assignment value that means "no value" | ||
- Javascript sets unassigned variables with a default value of `undefined` | ||
- Javascript never sets a value to `null`. It is used by programmers to indicate that a `var` has no value. | ||
- `undefined` is not valid in JSON while `null` is | ||
- `undefined` typeof is `undefined` | ||
- `null` typeof is an `object`. [Why?](http://www.2ality.com/2013/10/typeof-null.html) | ||
- Both are primitives | ||
- Both are [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) | ||
(`Boolean(undefined) // false`, `Boolean(null) // false`) | ||
- You can know if a variable is [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined) | ||
|
||
```javascript | ||
typeof variable === 'undefined'; | ||
``` | ||
|
||
```` | ||
- You can check if a variable is [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) | ||
|
||
```javascript | ||
variable === null | ||
```` | ||
- The **equality** operator considers them equal, but the **identity** doesn't | ||
```javascript | ||
null == undefined; // true | ||
|
||
null === undefined; // false | ||
``` | ||
``` | ||
|
||
``` |
Oops, something went wrong.