两次调用Array.sort不能正常工作吗? [英] Array.sort doesn't work properly when called twice?

查看:33
本文介绍了两次调用Array.sort不能正常工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经玩了一段时间了.当我运行对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆