【问题标题】:How to generate dynamic id for JavaScript object when inserting new element?插入新元素时如何为 JavaScript 对象生成动态 id?
【发布时间】:2018-08-02 01:45:41
【问题描述】:

我在里面有 JavaScript 对象元素的数组。示例如下:

var contacts =[{"id":1,"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1},{"id":2,"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1},{"id":3,"first":"Lisa","last":"Morgan","email":"lmorgan@gmail.com","phone":"(508) 233-8908","status":1},{"id":4,"first":"Dave","last":"Hart","email":"dhart@gmail.com","phone":"(509) 874-9411","status":1}];

我必须在该数组中插入/更新记录。我不确定检查该数组中是否存在记录的最佳方法是什么。如果存在则更新 js 对象,如果不存在则生成新的id。理想情况下,该 id 将是一个整数,并在 js 对象中的最高当前 id 之后开始。所以在数据中最高 id 值是4。如果我插入新记录id,新记录应该是5。有没有用 JavaScript 实现这一点的好方法?

function saveContact(){
    var frmObject = $(this),
        frmKey = $("#frm_id").val(),
        formData = frmObject.serialize(),
        contactRecord = contacts.find(item => item.id === Number(frmKey));;

        if (contactRecord) {
            contacts[frmKey] = getJSON(frmObject.serializeArray()); // If already exist in array then update object
        }else{
            frmKey = 'generate new id';
            contacts[frmKey] = getJSON(frmObject.serializeArray()); // If doesn't exist generate new key and insert object in array 
        }
}

【问题讨论】:

  • 如果您能够使用对象的对象(按 ID 索引)而不是对象数组,您的代码似乎会更容易使用 - 这是一个选项吗?每次都使用.find 似乎不是最好的主意。 (没关系真的,但代码会更干净)
  • @CertainPerformance Object of objects 是一个选项,所以如果你能提供一个如何生成id 的例子,这对我来说是最重要的部分。

标签: javascript jquery arrays generate


【解决方案1】:

这在评论中提到过,但我会稍微充实一下。

如果您的数据是以 ID 而非数组为键的对象,它将强制 ID 是唯一的,因为对象必须具有唯一的键。

例如:

var contacts =[{"id":1,"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1},{"id":2,"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1},{"id":3,"first":"Lisa","last":"Morgan","email":"lmorgan@gmail.com","phone":"(508) 233-8908","status":1},{"id":4,"first":"Dave","last":"Hart","email":"dhart@gmail.com","phone":"(509) 874-9411","status":1}];

// just a quick dirty conversion
let obj = contacts.reduce((a, c) => (a[c.id] = c, a), {})

//Object looks like:
console.log(obj)

// find the largest key // maybe a good way to decide the next key
largest_id = Math.max(...Object.keys(obj))
console.log("largest ID", largest_id)

// is ID 4 taken?
console.log("is there a 4", 4 in obj) //yes
// alternatively obj.hasOwnProperty('4')

// is 5?
console.log("is there a 5", 5 in obj) //no

// update ID 4:
obj['4'].first = "Mark"
console.log(obj['4'])

希望这是一种尝试这种方法而不是数组的动力。

【讨论】:

  • 我已经使用Math.max(Object.keys(obj)) 尝试了您提出的解决方案,但返回了NaN,而我使用了此代码Object.keys(obj).reduce((a, b) => obj[a] > obj[b] ? a : b); 并返回了4。您对为此目的使用reduce() 方法有什么意见吗?
  • 我认为reduce很好,但它的目的在视觉上不太明显。看起来您的 Math.max 缺少扩展 ... 运算符。
  • ... 是必需的吗?我以为这只是一个评论。以前从未见过。
  • @espresso_coffee 是的,要像这样使用Math.max,你需要它。它将数组扩展成单独的值,将Math.max( [1, 2, 3] ) 之类的东西变成Math.max( 1, 2, 3 )
  • 非常有趣,我刚刚测试过并且工作正常。这也将返回number 类型与我使用reduce 的解决方案返回string 类型。感谢您的帮助。
【解决方案2】:

在数组中找到最后一个对象并获取它的id:

contacts[contacts.length-1].id

然后只需添加1 即可获得下一个身份证号。

【讨论】:

  • 如果我决定使用对象的对象,在这种情况下会有什么解决方案?我不能在对象上使用.length 那么有没有其他方法可以找到对象的长度?
  • 您可以获得最后一个键,但这取决于您如何构造对象。读一读:stackoverflow.com/questions/4317456/… 如果你能给我一个对象的外观示例,我很乐意为你提供更多指导!
  • 我发现了这种方法并且似乎工作得很好var test = Object.keys(contacts).reduce((a, b) => contacts[a] > contacts[b] ? a : b); 返回最高的键值。所以我只是添加+1 来为我的对象生成新密钥。感谢您的帮助!
【解决方案3】:

您可以创建一个全局变量并将其用作计数器,每次新记录您可以将其增加一,对于现有的只是更新。

您可以将所有json存储在数据库中,在获取时只需计算数组元素/最后一个元素的ID并将其设置在计数器中。

此外,如果您不需要按顺序自动生成 id,您还可以使用随机函数每次生成唯一 id。

【讨论】:

    【解决方案4】:

    如果您将数据作为对象的对象来管理,您可以通过简单的方式实现这一点。

    var contacts  = {
    
       
      1: {
        first: "Mike",
        last: "Johnson",    
        email:"mjohnson@gmail.com",
        phone:"(203) 567-9055",
        status:"1"
     },
      2: {
        first: "John",
        last: "Dunn",    
        email:"jdunn@gmail.com",
        phone:"(319) 451-7889",
        status:"1"
     },
      3: {
        first: "Lisa",
        last: "Morgan",    
        email:"lmorgan@gmail.com",
        phone:"(508) 233-8908",
        status:"1"
     },
      4: {
        first: "Dave",
        last: "Hart",    
        email:"dhart@gmail.com",
        phone:"(509) 874-9411",
        status:"1"
     }
    };
    
    var frmKey = 5;
    if(contacts[frmKey]){
    console.log(contacts[frmKey]);
     // If already exist in array then update object
    }else{
      contacts[frmKey] = {first: "Lisa1",last: "Morgan1", email:"lmorgan1@gmail.com", phone:"(508) 233-8908", status:"1" };
    
      console.log("Added New Key::"+frmKey,contacts[frmKey]);
    
    }

    【讨论】:

      【解决方案5】:

      您可以使用Object 来存储您的Collection of Objects。每次在集合中注入一个对象,都会生成一个新的id(根据集合的长度),如果集合中插入的对象的id已经存在,则只进行一次更新。

      const collection = {};
      
      function insert(obj){
         // if id is set in object and object is already in Collection... 
         if(obj.id && collection.hasOwnProperty(obj.id) ){ 
           // Update object!
           collection[obj.id]= Object.assign(collection[ obj.id], obj) ;
         }else{ 
           // if provided object has no ID... generate it!
           if( !obj.id ) obj.id = Object.keys(collection).length;
           // insert provided object to collection;
           collection[obj.id]= obj;
         }
         // return generaed id;
         return obj.id;
      }
      
      
      // Let's test...
      
      let obj_1 ={"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1};
      
      let obj_2 = {"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1};
      
      // insert bth object
      insert(obj_1);
      insert(obj_2);
      // perform a change in object 2
      obj_2.first ='Joseph';
      // insert object 2 again...
      insert(obj_2);
      // object 2 has been updated, and all have unique ids
      console.log(collection);

      【讨论】:

      • 当然可以,但是如何判断集合是否有id:1。当您想要更新它时,您似乎不太可能引用确切的对象。
      • 对不起,我误解了你的问题。我用更好的方法更新了我的答案
      猜你喜欢
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多