【问题标题】:How can I implement a function that gets rid of reduntant Objets inside an Array of Objects in JavaScript?如何实现一个函数来消除 JavaScript 中对象数组中的冗余对象?
【发布时间】:2022-07-21 04:37:59
【问题描述】:

所以我正在尝试实现一个函数,该函数允许我在具有 3 个属性的 JS 对象内存储本地沙发的详细信息:

  • 一个ID(通过函数被产品的URL覆盖)

  • 颜色(通过事件监听器恢复)

  • 数量(恢复方式与颜色相同)

我已经拥有允许我使用数组在本地存储对象的功能:

function addedToCart(productObject) {
  let listOfProducts = getProducts();
  listOfProducts.push(productObject);
  registerProducts(listOfProducts);
}


function getProducts() {
  let listOfProducts = localStorage.getItem("listOfProducts");
  if (listOfProducts == null) {
    return [];
  } else {
    return JSON.parse(listOfProducts);
  }
}

function registerProducts(listOfProducts) {
  localStorage.setItem("listOfProducts", JSON.stringify(listOfProducts));
}

最后,我有 3 个事件监听器:

  1. 在用户选择选项时进行监听并获取颜色值
  2. 监听<input type="number"/>的变化,获取数量的值
  3. 在用户点击“添加到购物车”按钮时进行监听

这是我的 JS 代码

class classProductCartDetails {
  constructor(id, color, quantity) {
    this.id = id;
    this.color = color;
    this.quantity = quantity;
  }
}

let quantityProduct = document.getElementById("quantity");
let valid = true;

let colorValue = 0;
let quantityValue = 0;


itemColors.addEventListener("change", function (event) {
  colorValue = event.target.value;
  console.log(colorValue);
});



quantityProduct.addEventListener("input", function (event) {
  quantityValue = event.target.value;
  console.log(quantityValue);
});






addToCartButton.addEventListener("click", function () {
  if (quantityValue > 0 && quantityValue <= 100 && colorValue != 0) {
    let objectProduct = new classProductCartDetails(
      productId,
      colorValue,
      quantityValue
    );

    console.table(objectProduct);

    alert("Your product has been added to the cart!");
    addedToCart(objectProduct);
  }
  if(colorValue == 0 && quantityValue <= 0){
alert("WARNING! You must add the details of the product");
  }
else if (colorValue == 0) {
    alert("WARNING! You must add a color");
}
 else if (quantityValue <= 0) {
    alert("WARNING! The quantity inputted is invalid");
  }
  
});

问题?如果我只是点击两次“添加到购物车”按钮,或者如果我更改沙发的数量然后点击按钮,它将添加一个冗余 向数组添加新对象实例!

[{id: "107fb5b75607497b96722bda5b504926", color: "White", quantity: "1"},…]
0: {id: "107fb5b75607497b96722bda5b504926", color: "White", quantity: "1"}
1: {id: "107fb5b75607497b96722bda5b504926", color: "Blue", quantity: "1"}
2: {id: "107fb5b75607497b96722bda5b504926", color: "Blue", quantity: "1"}
3: {id: "107fb5b75607497b96722bda5b504926", color: "Blue", quantity: "2"}

如您所见,我们有 3 次相同的对象,2 次相同,1 次具有不同的数量。

我想实现一个函数,允许我单独检查一个对象的 ID、颜色和数量与数组中另一个对象的 ID、颜色和数量。

满足这些条件:

  • 如果ID、颜色和数量相同→删除多余的对象 问题

  • 如果只有 ID 和颜色相同但数量相同
    不同→将非冗余的数量值替换为冗余对象上的最新值并删除冗余对象

例如,第一个对象的属性与第二个,然后与第三个...然后第二个对象与第一个,第二个与第三个...依此类推,直到最后一个对象数组。

英语不是我的母语,所以你可能不明白我的意思,但不用担心,下面是这张照片的视觉表现: 还有 TD:DR

图中的话:

-没有冗余

-检测到冗余:

1.索引为 2 和 3 的已消除对象

2.将索引为 1 的对象的数量从 1 更改为 2

这将是本地存储上 JSON 的结果:

[{id: "107fb5b75607497b96722bda5b504926", color: "White", quantity: "1"},…]
0: {id: "107fb5b75607497b96722bda5b504926", color: "White", quantity: "1"}
1: {id: "107fb5b75607497b96722bda5b504926", color: "Blue", quantity: "2"}

我已经看过一些关于如何删除数组中冗余对象的帖子,但它们是静态数组

是否可以实现这样的功能(通过递归或迭代)?是不是太牵强了?有没有更简单的方法可以去除数组中的冗余对象?

任何帮助将不胜感激

顺便说一句,如果您对我的代码有任何建议或对我的代码有任何疑问,请不要犹豫!

【问题讨论】:

  • 能否提供addedToCart函数的代码。
  • addedToCart 的代码在我帖子顶部的第一个代码块中,虽然它很长,所以这里是代码:` function addedToCart(productObject) { let listOfProducts = getProducts( ); listOfProducts.push(productObject);注册产品(产品列表); } `

标签: javascript arrays class object local-storage


【解决方案1】:

你可以的

function addedToCart(productObject) {
  let listOfProducts = getProducts();
  listOfProducts = listOfProducts.filter(({productId, colorValue})=> {
    return !(productId == productObject.productId && colorValue == productObject.colorValue);
  })
  listOfProducts.push(productObject);
  registerProducts(listOfProducts);
}

这样,如果 productId 和 colorValue 相同,则从列表中删除上一个条目。它将被新的 productObject 替换。数量是否相同并不重要:在所有情况下,您都希望从 productObject 中获取数量。

【讨论】:

  • 非常感谢您的回复!我有一个问题,所以我注意到在您的箭头函数中,您的参数 2 值位于大括号之间。我知道您可以在大括号内对对象的属性进行分组,即:const {name, price, description} = couchProduct 但我不明白在函数参数中使用大括号,请问为什么?
  • @LePhenix47,原理和const {name, price, description} = couchProduct一样。这里({productId, colorValue})=&gt; {... 就像在做(arg) =&gt; { let {productId, colorValue} = arg; ...。方便...
  • 如果列表中已经存在该产品,我认为您希望将 productObject.quantity 添加到匹配的 listOfProducts 条目的数量属性中。
【解决方案2】:

所以我居然找到了解决办法:


  let verifyProducts = (objectToVerify, arrayOfObjects) => {
    let verifyProduct = arrayOfObjects.find((object) => { 
    const {id, color} = objectToVerify;

   object.id === id && object.color === color
    }); 
  
    if(verifyProduct){
      verifyProduct.quantity = Number(objectToVerify.quantity);
    }else{
      arrayOfObjects.push(objectToVerify);
    }
  }

【讨论】:

    【解决方案3】:

    你去...将你的数组传递给函数,函数将返回一个删除了冗余对象的数组。

    我们基本上从索引 0 开始遍历数组(所以最旧的条目在前)。

    对于我们检查的每个索引,我们当前对象的 id 和颜色的组合是否存在于数组中的更远位置(如果为真则意味着以下两种情况之一:

    • 存在一个对象,具有相同的 id、颜色和数量
    • 或存在一个对象,它具有相同的 id 和颜色,但数量不同

    而且由于我们只比较比我们当前对象“新”的对象,这两种情况都意味着我们当前索引处的对象是多余的......所以我们只是删除它。

    在我们的循环之后,我们通过删除所有那些现在未定义的索引来整理我们的数组,然后我们就有了最终的数组。

    如果您要从一开始就实现该代码并在每次添加新对象时使用它,您可以只检查最后一个对象(这样做留给读者练习)

    const arr = [{id : 1, color : "black", quantity: 1}, 
               {id : 1, color : "black", quantity: 1},
               {id : 1, color : "black", quantity: 1},
               {id : 2, color : "black", quantity: 1}];
               
               
    function getRidOfRedundant(arr) {
        let newArr = [...arr] //creating shallow copy of arr
        let compare = newArr.map(x => x.id + x.color);
        for (let i = 0; i < compare.length; i++) {
            if(compare.includes(compare[i], i + 1)) {
                delete (newArr[i])
            }
    
        }
        return newArr.filter(x => x !== undefined)
    }
    
    
    console.log(getRidOfRedundant(arr))

    也有可能直接干预对象的创建。在构造函数中有一个条件,当 id 和 color 相同时替换数组中的对象(我在这里使用类的静态属性,因为在构造函数中使用“外部”变量/对象可能有点粗略) - 不知道这将如何与您的 localStorage 内容交互/工作

    你也可以从构造函数中获取逻辑内容并创建一个函数,它基本上做同样的事情(找到现在冗余对象的索引并用新创建的对象覆盖它)

    class Product {
    
        static memory = [];
        static objects = []
    
        constructor(id, color, quantity) {
            this.id = id;
            this.color = color;
            this.quantity = quantity;
            
            if (Product.memory.includes(id + color)) {
                Product.objects[Product.memory.indexOf(id + color)] = this;
            } else {
                Product.memory.push(id + color);
                Product.objects.push(this);
            }
        }
    }
    
    new Product(id, color, quantity)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      • 2011-12-28
      • 2011-10-22
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多