True mastery came with a continues repetition of basic.
I always ask some simple puzzles for whiteboard interview for “trivial” coding task.
Just for 1 liner just for 5 minutes. The goal is check if candidate could code.
Belive me it is a lot of cases when they couldnt (it is a topic for next time).
Challenge
Write a function that get unique values from array
One of modern solutions
1 | function setToArray (arr) { |
The Full Story and Real Challenge
- Get unique elements of the array of simple values.
- The horror part - It should run on IE 7 !!!
- it should run fast as part of intensive calculations
- We could use an external lib
Solutions
General notes. I have learned that all laws of computer science do not always work with JS. Any native function could be tremendously faster of any algorithms. Let’s use jsperf for test and measurements.
Test data
Data drive perf results. So we could have worts cases and so one.
Let’s generate data randomly and make sure that we have duplicated values.
1 | const rnd = () => Math.floor((Math.random() * 10000000) + 1) % 200; |
The size of the array could have an impact for tests. So let’s have 10, 200 and 10000 length
1 | var a10 = [] ; a200 = [] ; a10000 = []; |
The super modern ES6 with Sets
I know that IE6 cut the crazy amount of variant but let’s try to use the most stylish way
1 | function setToArray (arr) { |
looks ultra short but as you can see
How it works
- We tune an array to set. we do filtering there
- we need to convert iterative to an array. “…” will do it.
Filter
Filter get access to an original array.
1 | function onlyUnique(value, index, self) { |
How it works
So we could scan an array and remove items that have the same value but different values. To get the index, we use a native indexOf. As you see all is native methods but anyway we have O(N^2) complexity.
One littel isuue filter doc IE9.
IndexOf IE7 friendly
It is first IE7 friendly but still O(N^2) solution but with native function.
1 | function uIndexOf (arr) { |
Let Sort
Well O(N^2) is too much. Native sort performs as O(N * log N). We could use it
1 | function compare(a,b) {ruturn a-b}; |
How it is work
To big CAUTIONS
- sort mutate an array
- default sort use a lexicology sort
1 | [11, 1, 111 , 12 ,2 ,7].sort() // [1, 11, 111, 12, 2, 7] |
1 | [11, 1, 111 , 12 ,2 ,7].sort((a, b) => a-b )// [1, 2, 7, 11, 12, 111] |
So now O(2N log N ) that much better than O(N^2). Still, we have an issue with mutability.
If it is better, we could fix it with good old slice, but it will kill all performance.
1 | function sortedUniqueNoMutate (arr) { |
Mutable version perform even faster that Set implementation, but if we add clone operation - it makes the function a bit faster then O(N^2) implementations
The map. O(1)
Javascript object is a hashmap. As you know read access for a hashMap is an O(1).
1 | function uExtraMap (arr) { |
How it work
We replace a check with read from map. We get O(N). But object is extra memory. Space complexity is groving.
The map without another array.
Let’s use an object key as a source of results
1 | function uExtraMapKeys (arr) { |
How it works
The idea is simple. We accumulate values in objects keys.
We win a space but lose a speed a bit.
IE 6 object keys
As we all know Object keys are available only in IE9. So IE 6 version, but still we have extra memory ((
1 | function uMapForIn (arr) { |
Summary
All code together with results avaliable here
PS - I use lib for It
Yep read Part II