-1

The following code is intended to remove the lowest number from an array of integers (numbers). I can't for the life of me understand why it is returning an array that is effected by the .sort().reverse().pop();.

I would have thought that assigning var numbersTest to numbers would mean that numbers itself would be unaffected by the aforementioned methods.

Can anyone please shed some light of this javaScript functionality?

function removeSmallest(numbers) {
  var numbersTest = numbers;
  var lowestNum = numbersTest.sort().reverse().pop();

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

  return numbers;
}

removeSmallest([1,2,3,4,5]);

This function returns [5, 4, 3, 2]

I want [2,3,4,5]

VoA
  • 503
  • 1
  • 6
  • 16
  • 3
    Arrays are objects, and are passed as ["value of a reference"](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language), meaning both `numbersTest` and `numbers` reference the same array. You have to clone the array using `var numbersTest = numbers.slice(0)` – adeneo Jan 24 '16 at 03:41
  • 1
    When you use the operator `=`, you have to understand what it actually means. `=` does not do a copy on the object data, instead it copies the reference. – Derek 朕會功夫 Jan 24 '16 at 03:46
  • Thank you! I've had a look at your link and https://davidwalsh.name/javascript-clone-array and now understand the problem. Sorry if this question was asked before - I didn't know how to word the problem in a Google search. I'll answer my own question and credit you. – VoA Jan 24 '16 at 03:51
  • Back to your actual problem, you really don't need this sort.reverse stuff, `Math.min.apply(null, numbers)` will do the job just fine. And the splice code is broken as well, test with `[2,3,1,1,4,5]`. – georg Jan 24 '16 at 04:38

4 Answers4

2

There are two ways of passing variables in javascript - by value or by reference. In few words: Only simple data types passed by value (such as numbers or strings), other types (arrays, objects, ...) are passing by reference. And if you have got many references to one object, performing changes on one of them will affect all (because there are just references). In first approximation you may think of it like symbolic links in unix or shortcuts in windows, when affecting symlink affects the file itself. See more information here: Javascript by reference vs. by value http://snook.ca/archives/javascript/javascript_pass

Community
  • 1
  • 1
1

When you say...

var anArray = [1, 2, 3];
var anotherArray = anArray;

Both these variables point to the same array in the memory.

This question discusses the ways to duplicate an array.

Community
  • 1
  • 1
Charlie
  • 22,886
  • 11
  • 59
  • 90
1

You can create a new array with a new reference like so:

var numbersTest = new Array(numbers);

This might be a simpler solution though:

function removeSmallest(numbers) {
    numbers.sort().splice(0, 1);
    return numbers;
}

The removeSmallest() function is flawed though as integers are sorted alphabetically in javascript. A better answer would be:

function removeSmallest(numbers) {
  numbers.sort(sortNumber).splice(0,1);
  return numbers;
}

function sortNumber(a,b) {
  return a - b;
}
Patrick
  • 185
  • 1
  • 11
0

Thanks to adeneo and Derek I think I understand the problem.

Basically, JavaScript objects (arrays such as my numbers array are one type of object) are assigned through "value of a reference" (unlike simple data types which are assigned through "value of a value").

What this means is that all variables assigned to a certain object hold the value of that object through reference to the original (i.e. through pointing to the original object) and not by having their own standalone value.

If the original is changed, the variable pointing to the original will have its value changed too (and vice versa).

To clone an array (which is what I wanted to do with my numbers array) you should simple use var numbersClone = numbers.slice(0). Reading this will explain.

Community
  • 1
  • 1
VoA
  • 503
  • 1
  • 6
  • 16