【问题标题】:How to maintain insertion order in javascript?如何在javascript中维护插入顺序?
【发布时间】:2020-01-14 04:39:37
【问题描述】:

这是我的代码生成的格式:

[
    {
        "certifications": [
            {
                "certificate": "NA",
                "completed_on": "2019-09-24T18:30:00.000Z",
                "tc_name": "TC-174195"
            }
        ],
        "firstname": "Dipak",
        "lastname": "Das",
        "email": "dasdipak99@gmail.com"
    }
]

我想设计如下格式:

[
  {
    firstname: "Dipak",
    lastname: "Das",
    email: "dasdipak99@gmail.com",
    certifications: [
      {
        certificate: "NA",
        completed_on: "2019-09-24T18:30:00.000Z",
        tc_name: "TC-174195"
      }
    ]
  }
]

下面是我的代码:

var user = [];
var certificate = {
  certifications: []
};

certificate["firstname"] = rows[0].firstname;
certificate["lastname"] = rows[0].lastname;
certificate["email"] = rows[0].email;

for (let i = 0; i < rows.length; ++i) {
  certificate.certifications.push({
    certificate: rows[i].certification_names,
    completed_on: rows[i].completed_on,
    tc_name: rows[i].tc_name
  });
}

任何想法如何维护插入顺序?我对javascript很陌生,如果我解释得不好,请道歉。

【问题讨论】:

  • 根据您的描述,它看起来像是_is_maintaining 插入顺序。你的对象首先有certifications,然后是firstname、lastname和email,这就是你应该得到的格式。
  • 嗨@JLRishe - 请指导我维护firstname 、lastname 、email 和certifications ?
  • 似乎你只需要做你已经在做的事情,但在末尾而不是开头插入certifications。我也有点好奇你在这里真正想要实现什么。试图以特定的顺序维护对象属性有点徒劳,我不建议你依赖它来做任何事情。
  • 同意@JLRishe。不知道为什么你需要维护一个你不应该依赖的对象的顺序。如果它是一个数组,情况就不同了。
  • @NijeeshJoshy JS 自 2015 年以来确实保证对于非整数键名。但依赖它仍然不是一个好主意。

标签: javascript arrays json ecmascript-6


【解决方案1】:

从 ES6 开始,有人声称订单是

  1. 第一个数字越来越多
  2. 按插入顺序排列的键

有这个blog post 和这个Stackoverflow thread。

但是你的台词

var certificate = {
  certifications: []
};

将certifications 设为第一个属性。所以你需要:

var certificate = {};

certificate["firstname"] = "Albert";
certificate["lastname"] = "Lee";
certificate["email"] = "a@b.com";
certificate["certifications"] = [];

certificate.certifications.push({
  certificate: "Java",
  completed_on: "2020/01/02",
  tc_name: "java2020"
});

console.log(certificate);

为了更好地保证顺序,请使用Map,保持键的原始插入顺序。通常你可能不需要它,但只是出于某种原因,如果你想要订单,并且可以在 for-of 循​​环中拥有这样的订单:

var certificate = new Map();

certificate.set('firstname', "Albert");
certificate.set('lastname', "Lee");
certificate.set('email', "a@b.com");
certificate.set("certifications", []);
certificate.get("certifications").push({
  "certificate": "Java",
  "completed_on": "2020/01/02",
  "tc_name": "java2020"
})

console.log(certificate);

for (e of certificate) console.log(e)

StackOverflow 不会为以下内容打印任何内容:

console.log(certificate);

使用 Node 或 Chrome,它是:

Map {
  'firstname' => 'Albert',
  'lastname' => 'Lee',
  'email' => 'a@b.com',
  'certifications' => [
    {
      certificate: 'Java',
      completed_on: '2020/01/02',
      tc_name: 'java2010'
    }
  ]
}

【讨论】:

    【解决方案2】:

    在名字、姓氏和电子邮件之后初始化空证书数组:

    let rows=[{certification_name:"NA",completed_on:"2019-09-24T18:30:00.000Z",tc_name:"TC-174195"}]
    
    let certificate = {}
    
    certificate["firstname"] = "Dipak"
    certificate["lastname"] = "Das"
    certificate["email"] = "dasdipak99@gmail.com"
    certificate["certifications"] = []
    for (let i = 0; i < rows.length; ++i) {
        certificate.certifications.push({
            "certificate": rows[i].certification_names,
            "completed_on": rows[i].completed_on,
            "tc_name": rows[i].tc_name
      })
    }
    
    console.log(certificate)

    【讨论】:

    • 插入顺序仍然不能保证,因为标准没有强制要求。最长的时间 Firefox 拒绝实施插入顺序,因为根据规范没有插入顺序是有效的,但用户设法促使 FF 开发人员这样做。请注意,将来任何 js 引擎都可能再次破坏这一点,并且 ES 标准委员会拒绝将其包含在标准中。 不要依赖于对象插入顺序!如果需要有序列表,请使用其他数据结构
    • 这种对无序数据结构“顺序”的错误解释非常糟糕,以至于go 编程语言的维护者添加了一个随机数生成器,以便他们的映射/哈希数据结构始终具有随机order - 他们认为随机数生成器的轻微减速值得给天真的程序员上一堂宝贵的课,我同意
    • @slebetman 我在所有主流浏览器上都进行了测试,效果很好。
    • 是的,但你仍然不应该这样做。它不是 javascript 语言的一部分——它是实现细节。永远不要依赖实现细节,因为它可以随时因任何原因而改变,例如。如果他们改变对象的结构以优化速度。如果发生这种情况,我知道很多开发人员会将中断的代码视为错误而不是浏览器
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2020-07-31
    • 1970-01-01
    • 2011-10-25
    • 2011-09-18
    • 2013-08-01
    • 1970-01-01
    相关资源
    最近更新 更多