【问题标题】:Add value into an array of Objects将值添加到对象数组中
【发布时间】:2016-05-27 19:03:33
【问题描述】:

我在 UI 表上显示了这个对象数组。它有 3 列,分别为 name、contact 和 id。

[Object, Object, Object]
0:Object
    name: "Rick"
    Contact: "Yes"
    id: 1
1:Object
    name:"Anjie"
    Contact:"No"
    id: 2
2:Object
    name:"dillan"
    Contact:"Maybe"
    id:3

现在,我在表格顶部添加一个新行。因此,新添加到对象数组中的行将如下所示。

[Object, Object, Object,Object]
0:Object  //newly added row. Since new row is added, it doesnt have any data.
 name: ""
 Contact: ""
 id: 
1:Object
 name: "Rick"
 Contact: "Yes"
 id: 1
2:Object
 name:"Anjie"
 Contact:"No"
 id: 2
3:Object
 name:"dillan"
 Contact:"Maybe"
 id:3

我希望对象数组看起来像这样,而不是上面一个。

[Object, Object, Object,Object]
0:Object  //newly added row. Since new row is added, it doesnt have any data.
 name: ""
 Contact: ""
 id: 4        
1:Object
 name: "Rick"
 Contact: "Yes"
 id: 1
2:Object
 name:"Anjie"
 Contact:"No"
 id: 2
3:Object
 name:"dillan"
 Contact:"Maybe"
 id:3

唯一的变化是第 0 个对象的 id 值。您可以看到我将其输入为 4。它将检查对象数组中的最大值以获取 id。在这种情况下,它是 3。因此它将增加 1,并将其作为新添加行的 id 值。

请有人告诉我如何实现这一点。

另外,我还有一个问题。

如果我的 id 值如下。

1
2
3
4
5
6

我删除了 4 和 5。所以新的行将是

1
2
5
6

在这里,它将检查最大长度为 4 并将 id 值 5 添加到新行。它看起来有点像这样。

5
1
2
5
6

在这种情况下,重复 5。我不想要这个。相反,我想看看哪个是赋予 id 的最高值,然后根据它增加 id。所以它应该看起来像这样。

7
1
2
5
6

【问题讨论】:

    标签: javascript arrays loops object underscore.js


    【解决方案1】:

    如果我理解正确,你只是想运行:

    array[0].id = array.length;
    

    添加行后立即。或者,如果您可以在添加新行时控制表示新行的对象的值,您可以将行添加为:

    {
      name:"",
      Contact:"",
      id: array.length + 1
    }
    

    编辑:

    响应您的编辑,显示可以删除数组的行。

    在这种情况下,要获取 ID 值,您有多种选择。

    一种是在删除时遍历数组的所有成员,并减少所有id大于删除行的行的id。这可能是最好的解决方案。

    示例代码:

    var delete = function(array, idToDelete) {
      for(var i = 0; i < array.length; i += 1) {
        if(array[i].id === idToDelete) {
          array.splice(i, 1);
        } else if (array[i].id > idToDelete) {
          array[i].id = array[i].id - 1;
        }
      }
    }
    

    如果出于某种原因,这不是一个选项,我建议遍历数组以找到其中的最高 ID,然后添加 1。

    var newId = array[0].id;
    for(var i = 0; i < array.length; i += 1) {
      if(array[i].id > newId) {
        newId = array[i].id;
      } 
    }
    array.splice(0, 0, {name:"", Contact:"", id: newId + 1});
    

    【讨论】:

    • array.length - 1 在第二种方法中? ;)
    • 不,看看OP的问题。无论出于何种原因,他的 id 都是 1 索引的。另外,在第二种方法中,不,它是+1。想想看;添加第一项时,数组的长度为 0,但所需的 id 为 1。
    • 哦,好的。 . .我误解了你的描述。 . .我的错(即,我认为“添加时”=“已经添加”)。然后我把数学搞砸了。 . .你知道吗 。 . .忽略它。 :D
    • @MaxGorenberg- 我编辑了我的问题,因为如果我只取最大长度就会出现问题。你能帮我解决这个新的测试用例吗?
    【解决方案2】:

    您可以使用它来查找下一个可用的最高 ID(假设它并非总是等于数组的长度):

    var newID = 1 + myArray.reduce(function(p, c) {
        return Math.max(c.id, p);
    }, 0);
    

    myArray 是你的数组。

    在 ES6 中你可以使用:

    var newID = 1 + myArray.reduce((p, c) => Math.max(c.id, p), 0)
    

    【讨论】:

    • 如果你还是要迭代,为什么不.reduce()?似乎有点浪费使用函数来创建一个值数组以传递给Math.max,而不是仅仅确定函数中的最大值。
    • @squint 我已经展示过了,虽然它可能更难理解。如果传递一个空数组,它还表明Math.max 版本存在问题。嗯……
    • @Alnitak:如果你像现在这样传递种子,空数组应该不会有问题,尽管我的想法更像(p, c) =&gt; c.id &gt; p ? c.id : p。但无论哪种方式都有效。
    • @Patrick 这个答案的重点是它考虑了现有值。我现在已经删除了基于 Math.max 的版本,因为当给定数组为空时它们会出现令人讨厌的边缘情况。
    • @squint 是的,如果您将 0 作为种子传递就可以了。 Math.max 本身的问题在于,给定一个空数组,它会返回 -Infinity。我在.reduce 中选择了Math.max 而不是三元运算符,因为它避免了术语的双重重复。
    【解决方案3】:

    如果只关心 ID 的唯一性,可以添加时间戳作为 ID

    假设您的数组名为peopleContact 您在对象数组中添加项目的代码如下所示。

    var person= new Object();
    person.name= "";
    person.Contact= "";
    person.id = Date.now();
    
    peopleContact.push(person);
    

    【讨论】:

    • 哇。从来没有想过这个。这对我来说是最好的办法。
    • @Patrick:你确定你能保证在同一毫秒内你永远不会将多个对象推入数组吗?
    • 小心 - JS 足够快,如果您不等待其他一些交互,两个 ID 可能会在同一毫秒内生成
    • @Alnitak,我同意,虽然发生这种情况的可能性很小,但它可能会发生。帕特里克,如果你认为这可能发生,你可以做一些事情,比如当他们打开页面时从服务器端获取用户 IP 地址,去掉“。”从它们中提取并将它们与 ID 连接起来。如果你愿意,我可以告诉你怎么做。甚至在最后连接数组长度。如果两个用户同时点击,数组长度也可以相同。在这种情况下,IP 地址的想法是唯一可行的。有什么想法或建议吗?
    • @Patrick:如果您担心必须迭代数组以获得最高 id,那么您最好关闭一个序列号并在每次添加时递增它。
    猜你喜欢
    • 2020-05-15
    • 2022-01-13
    • 2018-09-06
    • 2014-07-09
    • 2016-02-06
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多