Array.sort Doesn't Work Properly When Called Twice?
Solution 1:
The reason you're seeing what you're seeing is that val_a
and val_b
just contain references to the same array, which is also referenced from GLOBALS.items
. sort
changes the state of the array that all three of those variables are pointing to.
Variables contain values, not objects. When dealing with objects (including arrays), the value in the variable is a reference to the object, which actually exists elsewhere in memory. Think of that reference as a number telling the JavaScript engine where the object is elsewhere in memory. (More below.)
If you want three separate arrays (the original items
, then a copy sorted by val_a
, and another sorted by val_b
), you want to make a shallow copy of the array before sorting it, which you can do with slice
:
val_a = GLOBALS.items.slice().sort(...);
About the array being elsewhere in memory, here's a simpler example:
var a = [42]; // A variable with a reference to an array, which is// elsewhere in memory
That gives us this in memory:
+---------+ a<REF5512>--------->| (array) | +---------+ | 0: 42 | +---------+
(That REF5512
is just completely made up to make the point that a reference is a value. We never see the raw reference values.)
Then if we do:
var b = a; // A copy of that same reference
That gives us this in memory:
a<REF5512>---+ | +---------+ +----->| (array) | | +---------+ b<REF5512>---+ | 0: 42 | +---------+
If we change the state of the array (for instance, by sorting it), naturally that change is visible from either variable, as they're both referring to the same array:
b[0] = 67;
gives us
a<REF5512>---+ | +---------+ +----->| (array) | | +---------+ b<REF5512>---+ | 0: 67 | State of the array changed +---------+
slice
creates a new array with a copy of the values in the old array (just the values; the objects in your array aren't copied). So for instance:
b = a.slice();
Gives us:
+---------+ a<REF5512>--------->| (array) | +---------+ | 0: 67 | +---------+ +---------+ b<REF7341>--------->| (array) | +---------+ | 0: 67 | +---------+
Note how the reference in b
is no longer the same as in a
.
Side note: Your sort
callbacks can be much simpler:
val_a = GLOBALS.items.sort(function (a, b) {
returnparseFloat(a.val_a) - parseFloat(b.val_a);
});
The sort
callback just has to return a value less than zero (it doesn't have to be specifically -1), greater than zero (it doesn't have to be specifically 1), or equal to zero.
Post a Comment for "Array.sort Doesn't Work Properly When Called Twice?"