简体   繁体   English

具有相同键的JSON数组的总和

[英]Sum quantity of a JSON Array with same key

I have a problem with javascript objects with arrays trying to update "quantity" if the selected item is choosen again. 如果再次选择选定的项目,则带有数组的javascript对象出现问题,试图更新“数量”。

The object I use is defined like this: 我使用的对象的定义如下:

var Cart = {
    User: 0,
    Store: 0,
    UserID: 0, 
    Deliver: "Entrega",
    Date: "2014-01-01",
    Total: 0,
    ProductsCart: []
};

And in ProductsCart the array Im creating is the following: 在ProductsCart中,Im创建的数组如下:

Cart.ProductsCart.push({
        "ProductID": id,    //value sent from javascript function 
        "Quantity": Number(Quantity),
        "Price": Price.toFixed(2),
        "Name": name,
        "Desc": desc,
        "Date": date,
        "StoreID": store,
        "UserID": Number(UserID) //Special

The problem Im facing right now is that I have a javascript code to update the quantity of a selected product again, if exist it update the quantity but sometimes it works and sometimes not. 我现在面临的问题是,我有一个javascript代码来再次更新所选产品的数量,如果存在,它会更新数量,但有时可以,有时则不行。 This is the code 这是代码

  var temp = {},
            i;

        for (i = Cart.ProductsCart.length - 1; i >= 0; i -= 1) {
            ProductID = Cart.ProductsCart[i].ProductID;
            UserID = Cart.ProductsCart[i].NinoID;
            if (temp.hasOwnProperty(ProductID) && temp.hasOwnProperty(UserID)) {
                Cart.ProductsCart[temp[ProductID]].Quantity += Cart.ProductsCart[i].Quantity;
                //Splice to make one array with updated quantity?
                Cart.ProductsCart.splice(i, 1);
            } else {

                temp[ProductID] = i;
                //I need to identify one product per user and filter the productos by user so Im using that UserID to identify every array per user 
                temp[UserID] = UserID;
            }
        }
        console.log(Cart.ProductsCart);

Now the problem is that sometimes it add the specific quantity to the product like 现在的问题是,有时它会向产品添加特定数量,例如

  • Pizza, Quantity 1 披萨,数量1
  • Drink, Quantity 1 饮料,数量1

But for some reason for the same user or different user I try to add a Cake, Quantity 1 the pizza or the Drink is altered in its quantity and the cake doesnt exist anymore. 但是出于某种原因,出于同一用户或不同用户的原因,我尝试添加一个蛋糕,数量为1的比萨饼或饮料的数量发生了变化,因此该蛋糕不再存在。 Hope you can guide where its the problem Thanks in advance 希望您能指导问题出在哪里

EDIT------------- 编辑 - - - - - - -

The original script (mine) works with specific products, because doing some tests I found that Im using fullcalendar and on every click on a specific day the code doesnt work, but If i dont make a click the code works. 原始脚本(我的脚本)适用于特定产品,因为进行了一些测试,我发现Im使用fullcalendar,并且在特定日期的每次单击均不起作用,但是如果我不单击,则该代码有效。

Other thing is that Im using AJAX to bring the products by categories, the problem is not getting the ID, the problem is they dont identify the existing array 另一件事是,Im使用AJAX按类别带来产品,问题不是获取ID,问题是它们无法识别现有阵列

Suppose your array looks like this: 假设您的数组如下所示:

Pizza  4
Cake   3
Pizza  2
Pizza  5
Drink  2

At i = 2, you merge the two Pizza lines and splice one of them out: 在i = 2处,您合并了两个Pizza行并拼接其中的一个:

Pizza  4
Cake   3
Pizza  7
Drink  2

The problem is, now you Pizza line is at index 2, not 3, but you still have temp.Pizza = 3 . 问题是,现在您的Pizza行位于索引2,而不是3,但是您仍然有temp.Pizza = 3 So, at i = 0, you will incorrectly merge into the Drink line, which is now at index 3. 因此,在i = 0时,您将错误地合并到现在位于索引3的Drink行中。

One solution would be to go forward through the array when merging, instead of backward, and splice() the later repetitions of a product, leaving the first one at the index that you recorded. 一种解决方案是合并时向前遍历数组,而不是向后遍历,然后对产品的后续重复进行splice() ,将第一个重复保留在您记录的索引处。 Then just make sure that you do i -= 1 after splicing so that you'll look at that index again now that some other item has moved into that index. 然后只需确保在剪接后执行i -= 1 ,以便既然其他项已移入该索引,您将再次查看该索引。

Your problem is you're splicing your array mid-loop, which will cause undesired effects. 您的问题是您要在数组中段进行拼接,这会导致不良后果。 You are iterating over an array for every item in the array, yet you are changing the items in that array as you are iterating. 您正在为数组中的每个项目遍历数组,但是在迭代时正在更改该数组中的项目。 Can you see how this would cause you problems? 您能看到这会给您带来什么问题吗? :) :)

Take this example, which you can see demoed on this jsfiddle . 以这个示例为例,您可以在此jsfiddle上看到该示例

var arr = [
    "one",
    "two",
    "three",
    "four",
    "five"    
];

console.log('Without Splice ...');

for ( var i = 0; i <= arr.length - 1; i++ ) {
    console.log(arr[i]);
}

console.log('With Splice ...');

for ( var i = 0; i <= arr.length - 1; i++ ) {
    console.log(arr[i]);
    arr.splice(i, 1);
}

The first iteration logs each item, as you'd expect. 第一次迭代记录每个项目,正如您所期望的那样。 The second iteration, though, logs only every other item (one, three, five). 但是,第二次迭代仅记录其他所有项目(1、3、5)。 A safer bet would be to keep track of the items you want to remove in a temporary array, and then when you're iteration is done remove the items from your source based on what's in the temporary array. 比较安全的选择是跟踪要在临时数组中删除的项目,然后在完成迭代后,根据临时数组中的内容从源中删除项目。

Sorry, but I'm just not following your structure. 抱歉,我只是不了解您的结构。

What I would do is make it so that you have an array of Cart objects and each Cart object would have essential items like the user the cart belongs to and what items and what quantity of those items: 我要做的是使您拥有一个Cart对象数组,每个Cart对象将具有一些基本项目,例如购物车所属的用户以及哪些项目以及这些项目的数量:

/**
* @constructor
*/
var Cart = function(){
    var userID;
    var items = [];
    // array of Item
    ...
};

/**
* method for checking if item exists in cart
*/
Cart.prototype.hasItem = function(item){
    for (var i = 0; i < this.items.length; i++){
        if (this.items[i].itemId === item.itemId){
            return true;
        }
    }
    return false;
}


/**
* method for checking if item exists in cart
*/
Cart.prototype.updateItemQty= function(item, difference){
    for (var i = 0; i < this.items.length; i++){
        if (this.items[i].itemId === item.itemId){
            this.items[i].qty += difference;
        }
    }
}

Define Item: 定义项目:

var Item = function() {
    var ItemId;
    var qty;
    ...
}

then keep an array of Cart 然后保留一个购物车数组

var carts = [];

now provide a method or function for adding items to a particular cart 现在提供将商品添加到特定购物车的方法或功能

function addItem(item, userId){
    for (var i = 0; i < carts.length; i++){
        if (carts[i].userId === userId){
            // add or update item
            if (carts[i].hasItem(item)){
                carts[i].updateItemQty(item, 1);
            } else {
                carts[i].addItem(item);
            }
        } else {
            // add a new cart to carts array first
            // then add the item to that new cart
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM