两次调用Array.sort不能正常工作吗? [英] Array.sort doesn't work properly when called twice?
问题描述
我已经玩了一段时间了.当我运行对val b排序的函数时,为什么val_a被更改了?我该如何解决?当我分别运行该函数时,它们会起作用,但是当我一起运行它们时,某些地方会出错.
I've been playing this for a while. Why is val_a changed when I run the function to sort val b? How can I get around this? When I run the function separately they work, but when I run them together something goes wrong somewhere.
var GLOBALS = {"items":[]};
var val_a;
var val_b;
GLOBALS.items=[
{"thing":"one","val_a":0.5,"val_b":0.2},
{"thing":"two","val_a":0.2,"val_b":0.3},
{"thing":"three","val_a":0.3,"val_b":0.1}];
val_a = GLOBALS.items.sort(function (a, b) {
a=parseFloat(a.val_a);
b=parseFloat(b.val_a);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
val_b = GLOBALS.items.sort(function (a, b) {
a=parseFloat(a.val_b);
b=parseFloat(b.val_b);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
console.log("val_a",val_a);
console.log("val_b",val_b);
推荐答案
看到的原因是 val_a
和 val_b
仅包含引用到同一数组,该数组也从 GLOBALS.items
中引用. sort
更改所有三个变量都指向的数组的状态.
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.
变量包含值,而不是对象.处理对象(包括数组)时,变量中的值是对象的引用,该对象实际上存在于内存中的其他位置.可以将该引用视为告诉JavaScript引擎对象在内存中其他位置的数字.(下面有更多内容.)
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.)
如果您要三个独立的数组(原始的 items
,然后一个副本按 val_a
排序,另一个副本按 val_b
排序),想要在对数组进行排序之前对其进行浅表复制,您可以使用 slice
:
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
这使我们在记忆中:
+---------+
a<REF5512>--------->| (array) |
+---------+
| 0: 42 |
+---------+
(该 REF5512
完全是为了说明引用是一个值而构成的.我们从未看到过原始的引用值.)
(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
这使我们在记忆中:
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;
给我们
a<REF5512>---+
| +---------+
+----->| (array) |
| +---------+
b<REF5512>---+ | 0: 67 | State of the array changed
+---------+
slice
创建一个 new 数组,其中包含旧数组中值的副本(只是值;数组中的 objects 未复制).例如:
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();
给我们:
+---------+
a<REF5512>--------->| (array) |
+---------+
| 0: 67 |
+---------+
+---------+
b<REF7341>--------->| (array) |
+---------+
| 0: 67 |
+---------+
请注意, b
中的引用不再与 a
中的引用相同.
Note how the reference in b
is no longer the same as in a
.
旁注:您的 sort
回调可以更简单:
Side note: Your sort
callbacks can be much simpler:
val_a = GLOBALS.items.sort(function (a, b) {
return parseFloat(a.val_a) - parseFloat(b.val_a);
});
sort
回调只需要返回小于零(不必特定为-1),大于零(不必特定为1)的值,或等于零.
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.
这篇关于两次调用Array.sort不能正常工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!