0

So i tried to apply bubble sort technique to an associative array.

What i tried is making a normal array and then applying bubble sort. This worked , so now I'm trying to do the same for my associative array but I can't understand why it doesn't work, can someone explain and tell me how to do this?

Normal Array bubble sort code: <-- This one works

var numbers= new Array()

numbers[0] = 22;
numbers[1] = 3;
numbers[2] = 65;
numbers[3] = 75;
numbers[4] = 500;
numbers[5] = 2;
numbers[6] = 44;

for(var i=0; i<numbers.length; i++)
{
    if(numbers[i] < numbers[i+1])
    {
        var tempGetal = numbers[i];
        numbers[i] = numbers[i+1];
        numbers[i+1] = tempGetal;         
    }
}

console.log("Smallest number from array is " + tempGetal);

associative array bubble sort code: <-- Doesn't work

var celsius= new Array()

celsius["Monday"] = 22;
celsius["Tuesday"] = 3;
celsius["Wednesday"] = 65;
celsius["Thursday"] = 75;
celsius["Friday"] = 1;
celsius["Saterday"] = 2;
celsius["Sunday"] = 44;

for(var temp in celsius)
{
    if(celsius[temp] < celsius[temp+1])
    {
        var tempGetal = celsius[temp];
        celsius[temp] = celsius[temp+1];
        celsius[temp+1] = tempGetal;
    }
}

console.log("Smallest number from this array is " + tempGetal[temp]);

Can anyone tell me if the method I'm trying to apply is possible?

Thanks in advance!

AdrieanKhisbe
  • 3,899
  • 8
  • 37
  • 45
mike
  • 3
  • 1
  • Because temp+1 is parsed as "Monday1" instead of friday, therefore it is not even going to be joining the if at all. The "+" operator, in this case, is **concatenating**, not shifting. – briosheje Mar 10 '15 at 10:55
  • In JS an "associative array" is generally known as an Object: `var celsius= new Object();` or `var celsius= {};`. – Andy Mar 10 '15 at 10:57
  • 1
    Is that first bit of code actually sorting the array? It looks like just one pass (out of N passes) of a bubble sort. – JLRishe Mar 10 '15 at 11:08
  • The answer to "*Can anyone tell me if the method I'm trying to apply is possible?*" is yes, but the result is not what you expect. Object properties have no order, but they are **generally** returned in the order they are added, re–ordering requires removing and re–adding them. But some browsers maintain the original "order" (however that might have been established) regardless. For the record, the order that keys are visited in *for..in* is the same as that for the array returned by [*Object.keys*](http://ecma-international.org/ecma-262/5.1/#sec-15.2.3.14). But that might be trivia here. ;-) – RobG Mar 10 '15 at 11:33

2 Answers2

7

There are several reasons why your attempt didn't work, but there is a fundamental flaw in your assumption: the order of properties in an object is undefined, so you should not try to rearrange them.

There's really no reason to use sorting for this. Just go through the object once and find the lowest value:

var min = Infinity;
for(var day in celsius) {
    if(celsius[day] < min) {
        min = celsius[day];
    }    
}
console.log(min);

A fancier solution:

var celsius = [];

celsius["Monday"] = 22;
celsius["Tuesday"] = 3;
celsius["Wednesday"] = 65;
celsius["Thursday"] = 75;
celsius["Friday"] = 1;
celsius["Saterday"] = 2;
celsius["Sunday"] = 44;

var min = Object
  .keys(celsius)
  .map(function(key) {
    return celsius[key];
  })
  .reduce(function(last, next) {
    return last < next ? last : next;
  }, Infinity);

console.log(min);

Other problems with your approach:

  • Javascript does not have associative arrays. You should generally not create an array and assign named properties to it (that's what objects are for).
  • If you iterate through an object with for(var temp in celsius), temp will be the property names, not the temperatures or numerical indices.
  • With the previous bullet in mind, if temp has the value "Monday", then celsius[temp + 1] = tempGetal will assign tempGetal to the property Monday1.
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • Oh well, you've also integrated the fancier solution :P +1! – briosheje Mar 10 '15 at 11:09
  • Thank you all for explaining it so well! I now understand what I was doing wrong. – mike Mar 10 '15 at 11:10
  • the fancier solution just returns the **last** value for me, as `last` & `next` start as the keys and once you go through the first check you are returning the lowest value of those 2 elements, so `last` is now `3` you are checking `celsius[3] < celsius['Wednesday']` – RedSparr0w Nov 14 '17 at 20:47
  • 1
    @RedSparr0w Thank you for pointing that out. I've modified the example to something that works, while not quite as succinct. – JLRishe Nov 15 '17 at 00:12
  • Nice edit, seems to work pretty well, although i would recommend just using `var min = Object.values(celsius).reduce(function(last, next) { return last < next ? last : next; });` (doesn't support IE though) – RedSparr0w Nov 15 '17 at 01:54
  • 1
    @RedSparr0w I would have done that, but `Object.values` does not have IE support. Also, it's good to pass in `Infinity` to the `.reduce` part in case the array is empty. – JLRishe Nov 15 '17 at 01:57
  • Haha yeah just realized that after i posted it!, the for loop is definitely the most universal solution. – RedSparr0w Nov 15 '17 at 01:57
0

For the record, your bubble sort doesn't work correctly because you should keep sorting until nothing moves, e.g.

// Sort an array of Numbers
function bubbleSort(arr) {
  var oneMoved, // flag if one moved
      i,        // counter
      t;        // temp variable
  do {

    // reset flag 
    oneMoved = false;

    // reset counter
    i = arr.length - 1;

    while (i--) {

      // If array members are out of sequence, swap
      if (arr[i] > arr[i+1]) {
        t = arr[i];
        arr[i] = arr[i+1]
        arr[i+1] = t;

        // Remember that one moved
        oneMoved = true;
      }
    }

  // Keep going as long as one moved
  } while (oneMoved)

  // Not necessary as array sorted in place, but means function
  // can be chained
  return arr;
}

// Quick test
var arr = [0, 3, 6, -2, 3];

console.log(bubbleSort(arr)); // [-2, 0, 3, 3, 6]
RobG
  • 142,382
  • 31
  • 172
  • 209
  • Oh wow i hadn't even noticed my bubble sort was wrong. Thanks for replying so fast! – mike Mar 10 '15 at 11:56