【问题标题】:Maintaining array order in Javascript在Javascript中维护数组顺序
【发布时间】:2014-03-03 16:30:24
【问题描述】:

我是 JavaScript 新手,在处理数组时遇到问题,我希望数组按我明确编写的方式排序,而不是 JavaScript 决定它需要它的方式。

如果我们有一个数组

var array = {
    0: 'zero',
    4: 'four',
    2: 'two'
};

当我选择在控制台中显示它或对其进行迭代时,它会像这样重新排序

array = {
    0: 'zero',
    2: 'two',
    4: 'four'
};

到目前为止,我已经尝试了 2 个循环,for 循环,以及带有 in 语句的 for 循环。 两者都按照我假设的方式工作,因为他们使用密钥并向上/向下工作,使我指定的顺序绝对没用。

我如何按顺序编写/打印/使用我的数组,在其他语言(例如 PHP)中,它就像 PHP 一样简单

$array = array(
    0 => 'zero',
    4 => 'four',
    2 => 'two'
);

foreach($array as $key => $value)
    echo $key ."\n";

这会输出

0
4
2

提前致谢。

【问题讨论】:

  • 它实际上似乎是一个对象。
  • 伙计们,问题是:如何打印0 然后4 然后2for (var k in array) console.log(k)
  • 我已经阅读并回复了下面的所有解决方案,他们没有像你说的下面的答案,我谈到了迭代数组以按照明确的顺序写入/打印/处理它写在,还没有人解决这个问题,每个人都刚刚跳上乐队大喊“不是数组它是对象”,我的问题仍然没有答案。
  • @wared Read for..in > 以任意顺序迭代对象的可枚举属性。对于每个不同的属性,可以执行语句。
  • 它的意思是它所说的,你不清楚什么?不管是 Chrome、FireFox 还是 Sky Blue Pink。避免它的方法是使用Array 而不是Object,并使用数组迭代而不是对象迭代。去阅读我上面发布的链接以了解每个链接是什么,那里有示例。

标签: javascript php arrays loops


【解决方案1】:

您使用的是对象{},而不是数组[]。对象没有明确的顺序,而数组则有。这就是为什么你有你的问题。将您的 {} 更改为 [] 就可以了。您甚至可以使用对象数组。

var array = [
    {0: 'zero'}, 
    {4: 'four'}, 
    {2: 'two'}
];

这样循环

for(var i = 0; i < array.length; i++){
  console.log(array[i]);
}

给我们正常的订单。

Object {0: "zero"}
Object {4: "four"}
Object {2: "two"} 

另一个编辑:问题是你试图拥有一个像对象一样具有属性和值的数组,而不使用对象 {property: value} - 这实际上无法用数组完成。要像你想要的那样循环数组,就像

var arr = [1,2,3]

for(var i = 0; i < arr.length; i++){
  console.log(i) //1,2,3
}

但问题是,如上所述,您想要更复杂的数组,而您根本无法做到。

【讨论】:

  • 好吧,他不能只是更改初始声明;初始化语法也不同。
  • Pointy 这是我刚刚尝试过的,实际上它失败了,一个非常无用的声明。然而,除此之外,当我确实获得了创建数组的正确语法时,我的问题仍然没有得到解答,即如何迭代它并主键顺序,我只是再次尝试使用我提到的循环和我遇到的同样的问题与对象存在于数组中。
  • @cecilli0n 立即尝试。抱歉正在编辑答案。
  • 你也可以使用嵌套数组,比如[[0, 'zero'], [4, 'four'], [2, 'two']]
  • 这个答案严重混淆了本质上是一个简单的问题,其中 OP 不知道 ArrayObject 之间的区别或如何迭代它们中的任何一个。
【解决方案2】:

您需要了解ArrayObject 是什么,它们是根本不同的东西,并且行为不同。

数组

数组是类似列表的对象,其原型具有执行遍历和变异操作的方法。 JavaScript 数组的长度及其元素的类型都不是固定的。由于数组的大小长度随时会增长或缩小,因此 JavaScript 数组不能保证是密集的。一般来说,这些都是方便的特性;但如果这些特性不适合您的特定用途,您可以考虑使用类型化数组。

数组示例,注意神奇的length 属性,分配给数组的值总是在它们的索引位置找到;索引是从 0 到 2^32 - 1

// dense arrays
var array1 = [1, 2, 3];

array1.length === 3;
array1[0] === 1;

var array2 = [];

array2[0] = 1;
array2[1] = 2;
array2[2] = 3;

array2.length === 3;
array1[1] === 2;

var array3 = [];

array3.push(1);
array3.push(2);
array3.push(3);

array3.length === 3;
array3[2] === 3;

// and a sparse array
var array4 = [];

array4[0] = 1;
array4[2] = 2;
array4[4] = 3;

array4.length === 5;
array4[1] === undefined;

迭代数组for

var array = [1, 2, 3, 4, 5];

for (var index = 0; index < array.length; index += 1) { // counts from (index) 0 to 4
    console.log(index, array[index]); // outputs 0 1 \n 1 2 \n 2 3 \n 3 4 \n 4 5
}

对象

对象是属性的集合,属性是名称和值之间的关联。属性的值可以是函数,在这种情况下,属性称为方法。除了浏览器中预定义的对象外,您还可以定义自己的对象。

一个对象的例子,没有神奇的length属性。

var object1 = {
    'zero': 1,
    'one': 2,
    'two': 3
};

object1.zero === 1;

var object2 = {);

object2['zero'] = 1;
object2['one'] = 2;
object2['two'] = 3;

object2.one === 2;

var object3 = {);

object3.zero = 1;
object3.one = 2;
object3.two = 3;

object['two'] === 3;

迭代(枚举)一个对象for..in

var object = {
   one: 0,
   two: 1,
   three: 2
};

for (var property in object) {
    if (object.hasOwnProperty(property)) { // make sure the property belongs to object
        console.log(property, object[property]); // outputs (not necessarily this order)
                                                 // three 2 \n two 1 \n one 0
    }
};

如果您试图维护一个有序的对象,那么这不是 Javascript 的工作方式,对象的迭代(枚举)是任意的。您可以使用一些技术以已知顺序迭代(枚举)对象。这要求您在一个数组中保留一个有序的属性列表,并在迭代过程中使用该数组。

var object = {
   'c': 1,
   'z': 2,
   'b': 3,
   'a': 4
}

var propertyOrder = ['c', 'z', 'b', 'a'];

for (var index = 0; index < propertyOrder.length; index += 1) {
    console.log(index, propertyOrder[index], object[propertyOrder[index]]); // outputs 0 c 1 \n 1 z 2 \n 2 b 3 \n 3 a 4
}

【讨论】:

    【解决方案3】:

    我不明白。是什么让你认为 0、4、2 是“有序”的任何形式或形状?

    但是,显然您想要将数字和字符串保持在一起,按照您指定的顺序

    您的错误,如果您原谅我听起来可能有点刺耳,您似乎认为您可以使用索引或成员名称既是访问数据的手段和数据本身的一部分。

    你不能,也不应该。索引就是索引,名称就是名称,数据就是数据[1].

    以下是将数字和字符串保持在一起的两种实现方式:

    var pairs = [
        [0, "zero"],
        [4, "four"],
        [2, "two"]
    ];
    for (var index in pairs) {
        alert(pairs[index][0] + ": " + pairs[index][1]);
    };
    

    对于这个,我将数字和字符串对放在各自的数组中:位置 0 的数字,位置 1 的字符串。我将这些数组存储在 pairs 中。

    然后我用 for/in 迭代数组,在每次迭代中,它都会给我一个 pairs 数组的索引。

    然后我使用该索引访问pairs 中的正确子数组,并从位置 0 获取数字,从位置 1 获取字符串。

    var pairs = [
        {number: 0, string: "zero"},
        {number: 4, string: "four"},
        {number: 2, string: "two"}
    ];
    for (var index in pairs) {
        alert(pairs[index].number + ": " + pairs[index].string);
    };
    

    这个工作原理完全相同,除了将对存储在数组中,我将它们存储在对象中。

    这在 for 循环中具有更好的可读性:pairs[index][0]pairs[index][1] 并没有真正传达明确的含义。它只是告诉我们,“在具有给定索引的对中,获取项目 0 和 1”。

    但是,pairs[index].numberpairs[index].name 更清楚:“给定索引的对,给我编号和名称。”

    _

    脚注:

    [1a] 数字就是数字:我的银行帐号就是这样:一种识别我的银行账户的方法。对于我的姓名、我的 PIN 或我的账户余额,它没有任何意义——所有这些属性都可以作为属于我的银行账户的数据。

    [1b] 名字就是名字:我的名字只是一个名字。当你说我的时候,你可以用我的名字来指代我,这样别人就知道你在说谁了。我的名字没有传达任何关于我的爱好、我的 SSN 或我拥有什么品牌的汽车的信息——所有这些属性都可以作为描述我某些方面的数据。 (不过,按照惯例,您通常可以通过名字来判断一个人的性别)

    【讨论】:

    • 是什么让我觉得它有任何顺序?我按这个顺序写的事实。至于我使用成员名称来访问数据并与之分开,这是php中的常见做法,例如,如果我们有一个数据库,我们可以使用列名(键)来访问它的值,但是您的评论似乎为了让我相信 JavaScript 中的数组与 PHP 中的数组相比有很大的不同,我现在就去研究一下。
    • 没有。假设我有一个存储银行帐户信息的数据库表。列的名称(例如“account_balance”)不是该列数据的一部分。对于任何给定的行,该列的数据可以是 373.24、-12.47 或 1,000,000。 “account_balance”这个名字完全没有说明我的账户余额,也完全没有说明我的帐号。正如您所说,它用于访问它的价值。它不是该值的一部分。这在数据库、PHP、JavaScript 以及任何地方都是一样的。
    • 在您的主要答案中,您写了“索引是索引,名称是名称,数据是数据”,这可以理解为您在谈论数组的 3 个部分,其中让我相信您将数据定义为整个数组,为了清楚起见,最好只写一个索引是一个索引,一个值是一个值。此外,在上面第二条评论的开头部分,您使用术语数据,而在后面的部分中,您使用术语值。根据您的定义,这些术语都用于谈论同一件事,那么为什么不自始至终只使用一个术语呢?
    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2013-11-19
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多