【问题标题】:Preventing duplicate objects from being added to array?防止重复的对象被添加到数组中?
【发布时间】:2019-09-02 09:14:35
【问题描述】:

我正在为客户建立一个小商店并将信息存储为对象数组。但我想确保我没有创建“重复”对象。我见过类似的解决方案,但也许是我对编码的“新奇”让我无法在自己的代码中实现它们的要点,所以我想要一些针对我所做工作的建议。

我尝试将我的代码放入 if 查找中,如果没有“part”,我的变量正在寻找部件号,存在于代码中,然后添加该部件,但无法使其发挥作用。

这是我正在处理的功能:

   function submitButton(something) {
     window.scroll(0, 0);
     cartData = ($(this).attr("data").split(','));

     arrObj.push({
       part: cartData[0],
       description: cartData[1]
     });

   }

arrObj 被定义为一个全局变量,这是我在这里使用的,带有“部分”和“描述”,这是我试图从其他地方保存并输出到我的“#cart”的数据.我有那部分工作,我只想确保用户不能两次添加相同的项目。 (或更多次。)

对不起,如果我的代码是粗制滥造的或者我看起来很无知;我目前是一名试图弄清楚这些事情的学生,所以大部分 JS 和 Jquery 对我来说都是全新的。谢谢。

【问题讨论】:

  • 你需要if (!arrObj.some(item => item.part == cardData[0]) arrObj.push(...) (Array#some 测试函数是否对任何元素返回true)
  • 我可以在你们商店购买两个相同的零件吗?
  • Georg:你可以,但这是在其他地方处理的,而不是通过使用数据来处理的。所有这一切都是发回一封电子邮件,因此我将有一个不同的 POST 字段,其中将指定数量,并将该信息通过电子邮件发送给我的客户。它不需要影响数据,因为它存在。
  • @JoelPeterson Chris G 的回答也解决了你的问题...
  • 我希望这不是真正的客户和真正的商店。 20 年前这样的事情没什么大不了的,但现在你很快就会让那家商店被黑客入侵和诈骗。

标签: javascript arrays object


【解决方案1】:

您可以创建一个proxy 并使用Map 来保存和访问值,就像这样

let cart =  new Map([{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }].map(v=>[v.id,v]));

let handler = {
  set: function(target,prop, value, reciver){
     if(target.has(+prop)){
      console.log('already available')
     } else{
      target.set(prop,value)
     }
  },
  get: function(target,prop){
    return target.get(prop)
  }
}

let proxied = new Proxy(cart, handler)

proxied['1'] = {id:1,title:'Dog toy'}
proxied['3'] = {id:3,title:'Dog toy new value'}

console.log(proxied['3'])

【讨论】:

    【解决方案2】:

    假设 'part' 属性在每个 cartData 上都是唯一的,我只根据它进行检查。

      function submitButton(something) {
         window.scroll(0, 0);
         cartData = ($(this).attr("data").split(','));
    
         if(!isDuplicate(cartData))
         arrObj.push({
           part: cartData[0],
           description: cartData[1]
         });
    
       }
    
       const isDuplicate = (arr) => {
         for(obj of arrObj){
           if(arr[0] === obj.part) 
             return true;
         }
    
         return false;
       }
    

    如果您想同时检查 'part' 和 'description' 属性,可以将 if 语句替换为 if(arr[0] === obj.part && arr[1] === obj.description)

    【讨论】:

      【解决方案3】:

      感谢大家的建议。使用这个和朋友的帮助,这是有效的解决方案:

      function submitButton(something) {
        window.scroll(0,0);
        cartData = ($(this).attr("data").split(','));
      
      let cartObj = {
        part: cartData[0],
        description: cartData[1],
        quantity: 1
      }
      
      match = false
      arrObj.forEach(function(cartObject){
        if (cartObject.part == cartData[0]) {
        match = true;
      }
      })
      console.log(arrObj);
      if (!match) { 
          arrObj.push(cartObj); 
          }
      

      【讨论】:

      • 这比使用.some()复杂多了,看我的回复。
      【解决方案4】:

      好的,您有多种可能的方法来解决这个问题。所有这些都需要您在用户可以添加的项目上指定某种标识符。通常,这只是一个 ID 整数。

      因此,如果您有该整数,则可以执行以下检查以确保它不在对象数组中:

      let cart =  [{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }];
      
      function isInCart(id) {
        return cart.some(obj => obj.id === id);
      }
      
      console.log(isInCart(1));
      console.log(isInCart(3));

      另一种方法是通过它们的 id 将项目保存在一个对象中:

      let cart = { 1: { title: "Dog toy" }, 2: { title: "Best of Stackoverflow 2018" } };
      
      function isInCart(id) {
        if(cart[id]) return true;
        
        return false;
      }

      【讨论】:

      • return in forEach 没用。不返回外部函数
      • 没有。不在箭头函数中
      【解决方案5】:

      尝试使用indexOf检查对象是否存在,例如:

      var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
      
      console.log(beasts.indexOf('aaa'));
      // expected output: -1
      

      【讨论】:

      • 但是 OP 不能使用基元数组。不能将indexOf() 用于不同的对象引用,即使它们的所有属性和值都相同
      猜你喜欢
      • 2020-12-09
      • 2018-03-15
      • 2012-12-20
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 2011-02-17
      相关资源
      最近更新 更多