Created
June 19, 2019 21:46
-
-
Save aquaductape/a3d7c16b1d745bf993f68822925ef75d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Array prototype method, however this is not safe, since it is added to the global scope | |
// definedProperty makes method non-enumerable as well as adding new property to in this case, to Array prototype | |
// Array prototype method, however this is not safe, since it is added to the global scope | |
// definedProperty makes method non-enumerable as well as adding new property to in this case, to Array prototype | |
Object.defineProperty(Array.prototype, 'mySort', { | |
// webkit and chrome uses quicksort | |
// mozilla uses merge sort | |
// For my sort algorithm, it uses merge sort | |
// But I also chose chrome's interpretation of callback return boolean value, just because I mainly use chrome | |
value: function(callback) { | |
// if there is no callback | |
const defaultMerge = (left, right) => { | |
const results = []; | |
while (left.length && right.length) { | |
// toString method fails on null, using type coersion instead | |
if (left[0] + '' > right[0] + '') { | |
results.push(right.shift()); | |
} else { | |
results.push(left.shift()); | |
} | |
} | |
return [...results, ...left, ...right]; | |
}; | |
// if callback is provided | |
const callbackMerge = (left, right) => { | |
const results = []; | |
while (left.length && right.length) { | |
const result = callback(left[0], right[0]); | |
// to my understanding it seems to me that in chrome, | |
// it ignores boolean value from callback and strictly wants numerical sign values | |
// mozilla does accept boolean values | |
// in this case I'm choosing chrome's interpretation | |
if (typeof result === 'boolean') { | |
break; | |
} | |
if (Math.sign(result) === -1) { | |
results.push(left.shift()); | |
} else { | |
results.push(right.shift()); | |
} | |
} | |
return [...results, ...left, ...right]; | |
}; | |
const mergeSort = arr => { | |
if (arr.length === 1) { | |
return arr; | |
} | |
const mid = Math.floor(arr.length / 2); | |
const left = arr.slice(0, mid); | |
const right = arr.slice(mid); | |
return merge(mergeSort(left), mergeSort(right)); | |
}; | |
let merge = callbackMerge; | |
if (callback === undefined) { | |
merge = defaultMerge; | |
} | |
const length = this.length; | |
const cleanArr = []; | |
// removes empty slots | |
const undefinedValues = this.filter(el => { | |
if (el !== undefined) { | |
cleanArr.push(el); | |
} | |
return el === undefined; | |
}); | |
const sortedArr = mergeSort(cleanArr); | |
sortedArr.push(...undefinedValues); | |
const sortedArrLength = sortedArr.length; | |
// replaces array items with sorted array items | |
for (let i = 0; i < sortedArrLength; i++) { | |
this[i] = sortedArr[i]; | |
} | |
// sortedArr will be shorter if original array contains empty slots | |
// last remaining items will be duplicates | |
if (sortedArrLength < length) { | |
// deletes duplicates at end of array, by shortening the length | |
this.length = sortedArrLength; | |
// restores empty items at end of array, by extending the length | |
this.length = length; | |
} | |
return this; | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment