2
\$\begingroup\$

Looking for general feedback and praise. This is for learning an not implementation as I would expect the built is sort algos to be much faster.

Addressed issues here:

A package for sort algorithms

/***************************************************************************************************
 **ALGORITHMS
 ***************************************************************************************************/
 // self used to hold client or server side global
 (function (self) {
 "use strict";
 // holds (Pub)lic properties
 var Pub = {},
 // holds (Priv)ate properties
 Priv = {},
 // holds "imported" library properties
 $A;
 (function manageGlobal() {
 // Priv.g holds the single global variable, used to hold all packages
 Priv.g = '$A';
 if (self[Priv.g] && self[Priv.g].pack && self[Priv.g].pack.utility) {
 self[Priv.g].pack.algo = true;
 $A = self[Priv.g];
 } else {
 throw new Error("algo requires utility module");
 }
 }());
 Pub.swap = function (arr, i, j) {
 var temp = arr[i];
 arr[i] = arr[j];
 arr[j] = temp;
 };
 // checks to see if sorted
 Pub.isSorted = function (arr) {
 var i,
 length = arr.length;
 for (i = 1; i < length; i++) {
 if (arr[i] < arr[i - 1]) {
 return false;
 }
 }
 return true;
 };
 // repeatedly orders two items ( a bubble ) at a time
 Pub.bubbleSort = function (arr) {
 var index_outer,
 index_inner,
 swapped = false,
 length = arr.length;
 for (index_outer = 0; index_outer < length; index_outer++) {
 swapped = false;
 for (index_inner = 0; index_inner < length - index_outer; index_inner++) {
 if (arr[index_inner] > arr[index_inner + 1]) {
 Pub.swap(arr, index_inner, index_inner + 1);
 swapped = true;
 }
 }
 if (!swapped) {
 break;
 }
 }
 return arr;
 };
 // repeatedly finds minimum and places it the next index
 Pub.selectionSort = function (arr) {
 var index_outer,
 index_inner,
 index_min,
 length = arr.length;
 for (index_outer = 1; index_outer < length; index_outer++) {
 index_min = index_outer;
 for (index_inner = index_outer + 1; index_inner < length; index_inner++) {
 if (arr[index_inner] < arr[index_min]) {
 index_min = index_inner;
 }
 }
 if (index_outer !== index_min) {
 Pub.swap(arr, index_outer, index_min);
 }
 }
 return arr;
 };
 // repeatedly places next item in correct spot using a "shift"
 Pub.insertionSort = function (arr) {
 var index_outer,
 index_inner,
 value,
 length = arr.length;
 for (index_outer = 0; index_outer < length; index_outer++) {
 value = arr[index_outer];
 // JavaScript optimization - index_inner >=0 is removed
 // as the array index will return undefined for a negative index
 for (index_inner = index_outer - 1; (arr[index_inner] > value);
 index_inner--) {
 arr[index_inner + 1] = arr[index_inner];
 }
 arr[index_inner + 1] = value;
 }
 return arr;
 };
 // module complete, release to outer scope
 self[Priv.g] = $A.extendSafe(self[Priv.g], Pub);
 }(this));
asked Jan 19, 2014 at 23:44
\$\endgroup\$
1
  • \$\begingroup\$ Is your code faster than the built-in sort(), and if not, what is the purpose of this library ? \$\endgroup\$ Commented Jan 20, 2014 at 16:37

2 Answers 2

2
\$\begingroup\$

What is the reason for performing internal initialization inside the manageGlobal function? You're already inside a function, and you're operating on its local variables.

Here are some thoughts on the insertion sort (chosen at random):

  • You can start index_outer at 1 since the inner loop is empty at 0.

  • Use camelCase for variable and function names

  • Try to find names that are more descriptive. For example, upperIndex since it's the moving upper bound and shiftIndex since it's the index of the element to shift up.

answered Jan 20, 2014 at 0:27
\$\endgroup\$
0
2
\$\begingroup\$

Apart from the points I already mentioned in your previous post, I would like to point out that the JavaScript way of preserving the global object is not passing it as a parameter, but using Function.prototype.call, effectively turning your last line into

 }).call(this);

Also note that this code breaks if not executed in the global scope - which may always be the case if you use module packaging scripts such as RequireJS.

answered Jan 20, 2014 at 5:49
\$\endgroup\$
5
  • \$\begingroup\$ What is your reason for this? Functionally there is no difference between using call() vs the way I do it. \$\endgroup\$ Commented Jan 20, 2014 at 16:46
  • 1
    \$\begingroup\$ Mainly everyone reading your code will immediately know what this means whereas people who do not know Python might not recognize self. Additionally it's a convention thing, it's the way big libraries do it. Also, you should stick to the name the language you use uses, i.e. you could change every self to a this in Python, but you don't - because it's counter intuitive. \$\endgroup\$ Commented Jan 20, 2014 at 18:27
  • \$\begingroup\$ jQuery does it the way I do it - just FYI. \$\endgroup\$ Commented Jan 20, 2014 at 18:30
  • \$\begingroup\$ Ultimately it's of course your choice, but jQuery doesn't change the 'name' of the global object. Inside the closure window is still window. In your situation, where your library could also be used on the server side and the global object isn't window, I would just stick to this and the most concise way to do that is to use call IMHO. And you're asking for our opinion on your code ;) \$\endgroup\$ Commented Jan 20, 2014 at 19:48
  • \$\begingroup\$ O.K. will update. \$\endgroup\$ Commented Jan 23, 2014 at 22:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.