设置数组元素会更改所有具有相同名称的元素 [英] Setting Array element changes all elements with same name

查看:99
本文介绍了设置数组元素会更改所有具有相同名称的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是下面链接的后续帖子。我在那里得到的帮助表明我的代码在jsfiddle上可以正常工作,因此在创建嵌套数组并将对象推入它们时必须有一个我不理解的概念:
在JSON中更新elemint更新全部

This is a follow-on post to the link below. I received help there that showed my code works as expected on jsfiddle, so there must be a concept I am not understanding when creating nested arrays and pushing objects to them: Updating elemint in JSON updates ALL

这个问题听起来像是确切的问题,尽管我使用的是JavaScript,但我无法解释如何对用例应用正确的答案:

This question sounds like the exact issue, although in javascript for me, I am having but I cannot interpret how to apply the correct answer to my use case: How to avoid referencing the same index in an array (Java)?

这个订购界面有点不合常规,他们首先选择帐户,然后再选择任何产品时,必须将其添加到所有帐户。

This ordering UI is a little unorthodox where they select the accounts first, and then when they select any product after that, it has to be added to all accounts.

我的数组是JS:

runningOrdfers = {
"id": 1402846607011,
"status": "unsaved",
"accounts": [
    {
        "compid": 919759,
        "compname": null,
        "products": [
            {
                "BCINUM": "539504",
                "ITEMUNIT": "EA",
                "ORDERDETAILS": [
                    {
                        "SHIPDATEID": "69230",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "1"
                    },
                    {
                        "SHIPDATEID": "69231",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "2"
                    }
                ],
                "SHIPPINGCOMMENTS": ""
            }
        ]
    },
    {
        "compid": 920001,
        "compname": null,
        "products": [
            {
                "BCINUM": "539504",
                "ITEMUNIT": "EA",
                "ORDERDETAILS": [
                    {
                        "SHIPDATEID": "69230",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "1"
                    },
                    {
                        "SHIPDATEID": "69231",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "2"
                    }
                ],
                "POTEXT": "",
                "SHIPPINGCOMMENTS": ""
            }
        ]
    }
]

这是我创建对象并将其附加到数组的方式。首先,创建一个新订单:

Here is how I create and append objects to the array. First, create a new order:

var runningOrders = {};

function createNewOrder(event) {
    var uniqueID  = uniqueIdentifier();
    var accounts = [];
    var products = [];
    runningOrders.id = uniqueID;
    runningOrders.status = "unsaved";
    runningOrders["accounts"] = accounts;
    runningOrders.accounts["products"] = products;
    selectAccountsTab(event);
}

然后将帐户添加到订单中:

Then add the accounts to the order:

    function addAccountToOrder(compID) {
    getAccount(compID);
    var thisAccount = {};
    var n = savedAccountByCompID.length;
    for (var i = 0; i < n; i++) {
        var accountListObject  = savedAccountByCompID[i];
        thisAccount.compid = +accountListObject.COMPID;
        thisAccount.compname = +accountListObject.COMPNAME;
        thisAccount.products = [];
        runningOrders.accounts.push(thisAccount);
    }   
}

最后按顺序将产品添加到帐户中创建:

And finally add products to the accounts in the order just created:

    function setProductSelected(bcinum){
    var thisProductSelected = {};
    var thisProduct = "bcinum" + bcinum;
    var thisProductData = productData[thisProduct];

    thisProductSelected.BCINUM = thisProductData.BCINUM;
    thisProductSelected.ITEMUNIT = thisProductData.ITEMUNIT;
    thisProductSelected.ORDERDETAILS = [];

    thisOrderDetails = {
        SHIPDATEID: "69230",
        SHIPPERIODID: "2096",
        QUANTITY: ""
    };
    thisProductSelected.ORDERDETAILS.push(thisOrderDetails);

    thisOrderDetails = {
        SHIPDATEID: "69231",
        SHIPPERIODID: "2096",
        QUANTITY: ""
    };
    thisProductSelected.ORDERDETAILS.push(thisOrderDetails);

    var a = runningOrders.accounts.length;
    for (var ii = 0; ii < a; ii++) {
        currAccount = runningOrders.accounts[ii];    //possible problem? Loping over accounts and pushing same object?
        currAccount.products.push(thisProductSelected);
    }
}

我的函数迭代并更新索引的元素我导航到:

My function to iterate and update the elements for the index I navigate to:

function updateComments(compID,bcinum,comment) {
    var accounts = runningOrders.accounts;
    var n = accounts.length;
    for (i = 0; i < n; i++) {
        if (accounts[i].compid == compID) {
            var p = accounts[i].products.length;
            for (ii = 0; ii < p; ii++) {
                if (accounts[i].products[ii].BCINUM == bcinum) {
                    accounts[i].products[ii].SHIPPINGCOMMENTS = comment;
                }   
            }       
        }
    }
}

当我调用更新函数时,它将在所有索引位置更新SHIPPINGCOMMENTS,而不仅仅是基于compID的我要更新的位置:

When I call my update function, it is updating the SHIPPINGCOMMENTS at all index locations instead of just the one I wanted to be updated, which is based on compID:

updateComments(919759,539504,'sooner');

updateComments(919759,539504,'sooner');

推荐答案

不管可读性问题如何,这似乎都可以按照设计的方式工作,如图所示在此jsbin 中。似乎还有其他事情在发生。

Regardless of readbility issues this seems to work as designed as shown in this jsbin. It would seems there is something else going on.

这是不变性如何帮助很多人的一个很好的例子。围绕不变的数据结构设计代码可以减轻真理所在位置的复杂性和混乱。不幸的是,在JavaScript(默认情况下)中,对象是通过引用而不是通过值来管理的,因此语言本身不直接支持不可变对象。较新的版本(ECMAScript 5)支持 Object.freeze ,但是您需要在较旧/功能不正常的浏览器中使用polyfill。

This is a great example of how immutability can help a great deal. Designing your code around immutable data structures can alleviate complexity and confusion with where truth is. It is unfortunate that in JavaScript (by default) objects are managed by reference not by value so immutable objects are not directly supported by the language itself. Newer versions (ECMAScript 5) support the Object.freeze but you would need a polyfill in older / dysfunctional browsers.

要管理深度嵌套的数据结构的复杂性,可以帮助将数据封装在自定义对象中(在经典的面向对象设计中定义的对象,尽管在JavaScript中,这将是原型对象)。但是,这超出了原始问题的范围(请参见原型面向对象设计上的此博客文章。 )。

To manage the complexity of a deeply nested data structure it could help to encapsulate the data in a custom objects (object as defined in classic object oriented design, although in the case of JavaScript this would be a prototypical object). However, this is beyond the scope of the original question (see this blog post on prototypical object oriented design).

这篇关于设置数组元素会更改所有具有相同名称的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆