带有嵌套for循环的Javascript多维数组-无法正常工作

Posted

技术标签:

【中文标题】带有嵌套for循环的Javascript多维数组-无法正常工作【英文标题】:Javascript Multi-Dimensional Array with nested for Loop - Not working right 【发布时间】:2022-01-18 04:57:34 【问题描述】:

我有一个多维数组,我用两个 for 循环遍历它。如果满足某些条件,即 j 的值为 0,那么我想运行代码以将附加字段插入到数组中。如果 j 大于 0,我想运行一个函数,然后将此更新应用于数组。

我的问题是这个。循环似乎工作得很好,但它似乎在某个时候更新了数组的错误部分,我不确定为什么。我提供了一个测试数据集和我所指的代码。根据我在“calcCrowFliesTripMiles”函数中的代码,“legCrowFliesDistance”的 j=0 时的值应该等于“distanceFromKage”,但事实并非如此。我不确定这里发生了什么,但我似乎无法弄清楚。

function toRad (Value) 
  return Value * Math.PI / 180;


function calcCrow (lat1, lon1, lat2, lon2) 
  var R = 6371; // km

  var dLat = toRad(lat2 - lat1);
  var dLon = toRad(lon2 - lon1);
  var lat1 = toRad(lat1);
  var lat2 = toRad(lat2);

  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c;

  return d;


function calcCrowFliesTripMiles (combinations) 
  var stopArray = [];
  stopArray = [...combinations];

  for (let i = 0; i < stopArray.length; i++) 
    for (let j = 0; j < stopArray[i].length; j++) 
      if (j === 0) 
        stopArray[i][j].legCrowFliesDistance = stopArray[i][j].distanceFromKage;
       else 
        stopArray[i][j].legCrowFliesDistance = calcCrow(stopArray[i][(j - 1)].attributes[0].ucmlLat, stopArray[i][(j - 1)].attributes[0].ucmlLng, stopArray[i][j].attributes[0].ucmlLat, stopArray[i][j].attributes[0].ucmlLng);
      
    
  
  return stopArray;


var testArray = [
  [
    'ShipLOC': 'SANCO',
    'attributes': [
      'ucmlLat': '43.881431',
      'ucmlLng': '-92.496931',
    ],
    'totalLocationProductLength': 184,
    'distanceFromKage': 159.39214641507564,
  ], [
    'ShipLOC': 'MALVESEQ',
    'attributes': [
      'ucmlLat': '40.936476',
      'ucmlLng': '-72.653116',
    ],
    'totalLocationProductLength': 96,
    'distanceFromKage': 1691.1958136706187,
  ], [
    'ShipLOC': 'MONTRA',
    'attributes': [
      'ucmlLat': '42.286261',
      'ucmlLng': '-71.598679',
    ],
    'totalLocationProductLength': 476,
    'distanceFromKage': 1719.5409479837117,
  ], [
    'ShipLOC': 'SANCO',
    'attributes': [
      'ucmlLat': '43.881431',
      'ucmlLng': '-92.496931',
    ],
    'totalLocationProductLength': 184,
    'distanceFromKage': 159.39214641507564,
  , 
    'ShipLOC': 'MALVESEQ',
    'attributes': [
      'ucmlLat': '40.936476',
      'ucmlLng': '-72.653116',
    ],
    'totalLocationProductLength': 96,
    'distanceFromKage': 1691.1958136706187,
  ], [
    'ShipLOC': 'SANCO',
    'attributes': [
      'ucmlLat': '43.881431',
      'ucmlLng': '-92.496931',
    ],
    'totalLocationProductLength': 184,
    'distanceFromKage': 159.39214641507564,
  , 
    'ShipLOC': 'MONTRA',
    'attributes': [
      'ucmlLat': '42.286261',
      'ucmlLng': '-71.598679',
    ],
    'totalLocationProductLength': 476,
    'distanceFromKage': 1719.5409479837117,
  ], [
    'ShipLOC': 'MALVESEQ',
    'attributes': [
      'ucmlLat': '40.936476',
      'ucmlLng': '-72.653116',
    ],
    'totalLocationProductLength': 96,
    'distanceFromKage': 1691.1958136706187,
  , 
    'ShipLOC': 'MONTRA',
    'attributes': [
      'ucmlLat': '42.286261',
      'ucmlLng': '-71.598679',
    ],
    'totalLocationProductLength': 476,
    'distanceFromKage': 1719.5409479837117,
  ], [
    'ShipLOC': 'SANCO',
    'attributes': [
      'ucmlLat': '43.881431',
      'ucmlLng': '-92.496931',
    ],
    'totalLocationProductLength': 184,
    'distanceFromKage': 159.39214641507564,
  , 
    'ShipLOC': 'MALVESEQ',
    'attributes': [
      'ucmlLat': '40.936476',
      'ucmlLng': '-72.653116',
    ],
    'totalLocationProductLength': 96,
    'distanceFromKage': 1691.1958136706187,
  , 
    'ShipLOC': 'MONTRA',
    'attributes': [
      'ucmlLat': '42.286261',
      'ucmlLng': '-71.598679',
    ],
    'totalLocationProductLength': 476,
    'distanceFromKage': 1719.5409479837117,
  ],
];
console.log(calcCrowFliesTripMiles(testArray));
.as-console-wrapper  min-height: 100%!important; top: 0; 

编辑: 这是另一个要测试的数据集,它稍微小一些,是我正在提取的实际数据的极简版本。当我使用 testArray 和使用我的实际数组时得到的结果是不同的。当我创建测试数组时,我从控制台复制实际数据,删除该函数中未使用的一些属性字段,然后将数据分配给数组。我不知道为什么两者的结果会不同,因为数据看起来完全一样,不包括附加属性字段。

数据:

[
          [
              
                  "ShipLOC": "SANCO",
                  "attributes": [
                      
                          "ucmlLat": "43.881431",
                          "ucmlLng": "-92.496931",
                         
                      
                  ],
                  "totalLocationProductLength": 184,
                  "distanceFromKage": 159.39214641507564,
                 
              
          ],
          [
              
                  "ShipLOC": "MALVESEQ",
                  "attributes": [
                      
                          "ucmlLat": "40.936476",
                          "ucmlLng": "-72.653116",
                          
                      
                  ],
                  "totalLocationProductLength": 96,
                  "distanceFromKage": 1691.1958136706187,
                  
              
          ],
          [
              
                  "ShipLOC": "SANCO",
                  "attributes": [
                      
                          "ucmlLat": "43.881431",
                          "ucmlLng": "-92.496931",
                          
                      
                  ],
                  "totalLocationProductLength": 184,
                  "distanceFromKage": 159.39214641507564,
                  
              ,
              
                  "ShipLOC": "MALVESEQ",
                  "attributes": [
                      
                          "ucmlLat": "40.936476",
                          "ucmlLng": "-72.653116",
                         
                      
                  ],
                  "totalLocationProductLength": 96,
                  "distanceFromKage": 1691.1958136706187,
                  
              
          ]
      ]
        
When I run the code after assigning the above data to testArray, these are the results I get:

[
          [
              
                  "ShipLOC": "SANCO",
                  "attributes": [
                      
                          "ucmlLat": "43.881431",
                          "ucmlLng": "-92.496931",
                         
                      
                  ],
                  "totalLocationProductLength": 184,
                  "distanceFromKage": 159.39214641507564,
                 
              
          ],
          [
              
                  "ShipLOC": "MALVESEQ",
                  "attributes": [
                      
                          "ucmlLat": "40.936476",
                          "ucmlLng": "-72.653116",
                          
                      
                  ],
                  "totalLocationProductLength": 96,
                  "distanceFromKage": 1691.1958136706187,
                  
              
          ],
          [
              
                  "ShipLOC": "SANCO",
                  "attributes": [
                      
                          "ucmlLat": "43.881431",
                          "ucmlLng": "-92.496931",
                          
                      
                  ],
                  "totalLocationProductLength": 184,
                  "distanceFromKage": 159.39214641507564,
                  
              ,
              
                  "ShipLOC": "MALVESEQ",
                  "attributes": [
                      
                          "ucmlLat": "40.936476",
                          "ucmlLng": "-72.653116",
                         
                      
                  ],
                  "totalLocationProductLength": 96,
                  "distanceFromKage": 1691.1958136706187,
                  
              
          ]
      ]
        

使用 testArray 时的结果:

[
    [
        
            "ShipLOC": "SANCO",
            "attributes": [
                
                    "ucmlLat": "43.881431",
                    "ucmlLng": "-92.496931"
                
            ],
            "totalLocationProductLength": 184,
            "distanceFromKage": 159.39214641507564,
            "legCrowFliesDistance": 159.39214641507564
        
    ],
    [
        
            "ShipLOC": "MALVESEQ",
            "attributes": [
                
                    "ucmlLat": "40.936476",
                    "ucmlLng": "-72.653116"
                
            ],
            "totalLocationProductLength": 96,
            "distanceFromKage": 1691.1958136706187,
            "legCrowFliesDistance": 1691.1958136706187
        
    ],
    [
        
            "ShipLOC": "SANCO",
            "attributes": [
                
                    "ucmlLat": "43.881431",
                    "ucmlLng": "-92.496931"
                
            ],
            "totalLocationProductLength": 184,
            "distanceFromKage": 159.39214641507564,
            "legCrowFliesDistance": 159.39214641507564
        ,
        
            "ShipLOC": "MALVESEQ",
            "attributes": [
                
                    "ucmlLat": "40.936476",
                    "ucmlLng": "-72.653116"
                
            ],
            "totalLocationProductLength": 96,
            "distanceFromKage": 1691.1958136706187,
            "legCrowFliesDistance": 1657.5070148937111
        
    ]
]

使用实际数据时的结果(删除了大部分属性字段):

[
    [
        
            "ShipLOC": "SANCO",
            "attributes": [
                
                    
                    "ucmlLat": "43.881431",
                    "ucmlLng": "-92.496931",
                    
                
            ],
            "totalLocationProductLength": 184,
            "distanceFromKage": 159.39214641507564,
            "legCrowFliesDistance": 159.39214641507564
        
    ],
    [
        
            "ShipLOC": "MALVESEQ",
            "attributes": [
                
                    "ucmlLat": "40.936476",
                    "ucmlLng": "-72.653116",
                    
                
            ],
            "totalLocationProductLength": 96,
            "distanceFromKage": 1691.1958136706187,
            "legCrowFliesDistance": 1657.5070148937111
        
    ],
    [
        
            "ShipLOC": "SANCO",
            "attributes": [
                
                    "ucmlLat": "43.881431",
                    "ucmlLng": "-92.496931",
                   
                
            ],
            "totalLocationProductLength": 184,
            "distanceFromKage": 159.39214641507564,
            "legCrowFliesDistance": 159.39214641507564
        ,
        
            "ShipLOC": "MALVESEQ",
            "attributes": [
                
                    "ucmlLat": "40.936476",
                    "ucmlLng": "-72.653116",
                    
                
            ],
            "totalLocationProductLength": 96,
            "distanceFromKage": 1691.1958136706187,
            "legCrowFliesDistance": 1657.5070148937111
        
    ]
]

【问题讨论】:

我更新了我的帖子。我相信这是重现问题的极简主义。 【参考方案1】:

我查看了您的代码,对我来说,父数组中每个数组的第一个元素具有与legCrowFliesDistance 相同的值。我发现您试图在您的 calcCrow 函数中重新声明变量 lat1lat2。我将它们重命名为lat1radlat2rad,它似乎正如你所描述的那样工作。我不确定这是否是您正在寻找的修复程序,但我没有其他输出可以与之比较。

这是代码:

let testArray = [
  [
    
      "ShipLOC": "SANCO",
      "attributes": [
                                  
          "ucmlLat": "43.881431",
          "ucmlLng": "-92.496931",
        
      ],
      "totalLocationProductLength": 184,
      "distanceFromKage": 159.39214641507564
    
  ],
  [
    
      "ShipLOC": "MALVESEQ",
      "attributes": [
                                 
          "ucmlLat": "40.936476",
          "ucmlLng": "-72.653116",
        
      ],
      "totalLocationProductLength": 96,
      "distanceFromKage": 1691.1958136706187
    
  ],
  [
    
      "ShipLOC": "MONTRA",
      "attributes": [
                                
          "ucmlLat": "42.286261",
          "ucmlLng": "-71.598679",
            
        
      ],
      "totalLocationProductLength": 476,
      "distanceFromKage": 1719.5409479837117,
        
    
  ],
  [
    
      "ShipLOC": "SANCO",
      "attributes": [
                                 
          "ucmlLat": "43.881431",
          "ucmlLng": "-92.496931",
            
        
      ],
      "totalLocationProductLength": 184,
      "distanceFromKage": 159.39214641507564,
    ,
    
      "ShipLOC": "MALVESEQ",
      "attributes": [
                                 
          "ucmlLat": "40.936476",
          "ucmlLng": "-72.653116",
        
      ],
      "totalLocationProductLength": 96,
      "distanceFromKage": 1691.1958136706187
    
  ],
  [
    
      "ShipLOC": "SANCO",
      "attributes": [
                                  
          "ucmlLat": "43.881431",
          "ucmlLng": "-92.496931",                          
        
      ],
      "totalLocationProductLength": 184,
      "distanceFromKage": 159.39214641507564
    ,
    
      "ShipLOC": "MONTRA",
      "attributes": [
                                  
          "ucmlLat": "42.286261",
          "ucmlLng": "-71.598679",                          
        
      ],
      "totalLocationProductLength": 476,
      "distanceFromKage": 1719.5409479837117
    
  ],
  [
    
      "ShipLOC": "MALVESEQ",
      "attributes": [
                                 
          "ucmlLat": "40.936476",
          "ucmlLng": "-72.653116",
            
        
      ],
      "totalLocationProductLength": 96,
      "distanceFromKage": 1691.1958136706187
    ,
    
      "ShipLOC": "MONTRA",
      "attributes": [
                                  
          "ucmlLat": "42.286261",
          "ucmlLng": "-71.598679",
        
      ],
      "totalLocationProductLength": 476,
      "distanceFromKage": 1719.5409479837117
    
  ],
  [
    
      "ShipLOC": "SANCO",
      "attributes": [
                                  
          "ucmlLat": "43.881431",
          "ucmlLng": "-92.496931",
            
        
      ],
      "totalLocationProductLength": 184,
      "distanceFromKage": 159.39214641507564
    ,
    
      "ShipLOC": "MALVESEQ",
      "attributes": [
        
          "ucmlLat": "40.936476",
          "ucmlLng": "-72.653116",
        
      ],
      "totalLocationProductLength": 96,
      "distanceFromKage": 1691.1958136706187
    ,
    
      "ShipLOC": "MONTRA",
      "attributes": [
                                  
          "ucmlLat": "42.286261",
          "ucmlLng": "-71.598679",
        
      ],
      "totalLocationProductLength": 476,
      "distanceFromKage": 1719.5409479837117
    
  ],
  [
    
      "ShipLOC": "SANCO",
      "attributes": [
                                  
          "ucmlLat": "43.881431",
          "ucmlLng": "-92.496931",
        
      ],
      "totalLocationProductLength": 184,
      "distanceFromKage": 159.39214641507564
    ,
    
      "ShipLOC": "MALVESEQ",
      "attributes": [
        
          "ucmlLat": "40.936476",
          "ucmlLng": "-72.653116",
        
      ],
      "totalLocationProductLength": 96,
      "distanceFromKage": 1691.1958136706187
    ,
    
      "ShipLOC": "MONTRA",
      "attributes": [
                                  
          "ucmlLat": "42.286261",
          "ucmlLng": "-71.598679",
        
      ],
      "totalLocationProductLength": 476,
      "distanceFromKage": 1719.5409479837117
    
  ]
];

console.log(calcCrowFliesTripMiles(testArray));

function calcCrowFliesTripMiles (combinations) 
  let stopArray = [];
  stopArray = [...combinations];
  for (let i =0; i < stopArray.length; i++) 
    for (let j=0; j < stopArray[i].length; j++) 
      if (j===0)
        stopArray[i][j].legCrowFliesDistance = stopArray[i][j].distanceFromKage
       else 
        stopArray[i][j].legCrowFliesDistance = calcCrow(
          stopArray[i][(j -1)].attributes[0].ucmlLat,
          stopArray[i][(j -1)].attributes[0].ucmlLng,
          stopArray[i][j].attributes[0].ucmlLat,
          stopArray[i][j].attributes[0].ucmlLng
        );
      
    
  
  return stopArray;


function calcCrow(lat1, lon1, lat2, lon2) 
  const R = 6371; // km
  let dLat = toRad(lat2-lat1);
  let dLon = toRad(lon2-lon1);
  let lat1rad = toRad(lat1);
  let lat2rad = toRad(lat2);

  let a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1rad) * Math.cos(lat2rad); 
  let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  let d = R * c;
  return d;

    
// Converts numeric degrees to radians
function toRad(Value) 
  return Value * Math.PI / 180;

希望这会有所帮助!

编辑:

这是我在控制台中得到的:

[
  [
    
      "ShipLOC":"SANCO",
      "attributes":[
        
          "ucmlLat":"43.881431",
          "ucmlLng":"-92.496931"
        
      ],
      "totalLocationProductLength":184,
      "distanceFromKage":159.39214641507564,
      "legCrowFliesDistance":159.39214641507564
    
  ],
  [
    
      "ShipLOC":"MALVESEQ",
      "attributes":[
        
          "ucmlLat":"40.936476",
          "ucmlLng":"-72.653116"
        
      ],
      "totalLocationProductLength":96,
      "distanceFromKage":1691.1958136706187,
      "legCrowFliesDistance":1691.1958136706187
    
  ],
  [
    
      "ShipLOC":"MONTRA",
      "attributes":[
        
          "ucmlLat":"42.286261",
          "ucmlLng":"-71.598679"
        
      ],
      "totalLocationProductLength":476,
      "distanceFromKage":1719.5409479837117,
      "legCrowFliesDistance":1719.5409479837117
    
  ],
  [
    
      "ShipLOC":"SANCO",
      "attributes":[
        
          "ucmlLat":"43.881431",
          "ucmlLng":"-92.496931"
        
      ],
      "totalLocationProductLength":184,
      "distanceFromKage":159.39214641507564,
      "legCrowFliesDistance":159.39214641507564
    ,
    
      "ShipLOC":"MALVESEQ",
      "attributes":[
        
          "ucmlLat":"40.936476",
          "ucmlLng":"-72.653116"
        
      ],
      "totalLocationProductLength":96,
      "distanceFromKage":1691.1958136706187,
      "legCrowFliesDistance":1657.5070148937111
    
  ],
  [
    
      "ShipLOC":"SANCO",
      "attributes":[
        
          "ucmlLat":"43.881431",
          "ucmlLng":"-92.496931"
        
      ],
      "totalLocationProductLength":184,
      "distanceFromKage":159.39214641507564,
      "legCrowFliesDistance":159.39214641507564
    ,
    
      "ShipLOC":"MONTRA",
      "attributes":[
        
          "ucmlLat":"42.286261",
          "ucmlLng":"-71.598679"
        
      ],
      "totalLocationProductLength":476,
      "distanceFromKage":1719.5409479837117,
      "legCrowFliesDistance":1701.836066634145
    
  ],
  [
    
      "ShipLOC":"MALVESEQ",
      "attributes":[
        
          "ucmlLat":"40.936476",
          "ucmlLng":"-72.653116"
        
      ],
      "totalLocationProductLength":96,
      "distanceFromKage":1691.1958136706187,
      "legCrowFliesDistance":1691.1958136706187
    ,
    
      "ShipLOC":"MONTRA",
      "attributes":[
        
          "ucmlLat":"42.286261",
          "ucmlLng":"-71.598679"
        
      ],
      "totalLocationProductLength":476,
      "distanceFromKage":1719.5409479837117,
      "legCrowFliesDistance":173.81078287083193
    
  ],
  [
    
      "ShipLOC":"SANCO",
      "attributes":[
        
          "ucmlLat":"43.881431",
          "ucmlLng":"-92.496931"
        
      ],
      "totalLocationProductLength":184,
      "distanceFromKage":159.39214641507564,
      "legCrowFliesDistance":159.39214641507564
    ,
    
      "ShipLOC":"MALVESEQ",
      "attributes":[
        
          "ucmlLat":"40.936476",
          "ucmlLng":"-72.653116"
        
      ],
      "totalLocationProductLength":96,
      "distanceFromKage":1691.1958136706187,
      "legCrowFliesDistance":1657.5070148937111
    ,
    
      "ShipLOC":"MONTRA",
      "attributes":[
        
          "ucmlLat":"42.286261",
          "ucmlLng":"-71.598679"
        
      ],
      "totalLocationProductLength":476,
      "distanceFromKage":1719.5409479837117,
      "legCrowFliesDistance":173.81078287083193
    
  ],
  [
    
      "ShipLOC":"SANCO",
      "attributes":[
        
          "ucmlLat":"43.881431",
          "ucmlLng":"-92.496931"
        
      ],
      "totalLocationProductLength":184,
      "distanceFromKage":159.39214641507564,
      "legCrowFliesDistance":159.39214641507564
    ,
    
      "ShipLOC":"MALVESEQ",
      "attributes":[
        
          "ucmlLat":"40.936476",
          "ucmlLng":"-72.653116"
        
      ],
      "totalLocationProductLength":96,
      "distanceFromKage":1691.1958136706187,
      "legCrowFliesDistance":1657.5070148937111
    ,
    
      "ShipLOC":"MONTRA",
      "attributes":[
        
          "ucmlLat":"42.286261",
          "ucmlLng":"-71.598679"
        
      ],
      "totalLocationProductLength":476,
      "distanceFromKage":1719.5409479837117,
      "legCrowFliesDistance":173.81078287083193
    
  ]
]

【讨论】:

【参考方案2】:

经过大量故障排除后,我想出了一个可行的解决方案,但我不知道它为什么有效,只是它确实有效。我使用 JSON.stringify 将我的数据转换为 JSON,然后使用 JSON.parse 解析它,然后之前无法正常工作的函数正常工作。这是我唯一更改的代码行。

原代码:

console.log(calcCrowFliesTripMiles(this.state.allCombinations))

新代码:

console.log(calcCrowFliesTripMiles(JSON.parse(JSON.stringify(this.state.allCombinations))))

【讨论】:

我认为这个解决方案可能有效,因为调用 JSON.parseJSON.stringify 正在创建无法变异的原始克隆。 stopArray = [...combinations]; 行正在创建一个浅拷贝,这意味着嵌套数组仍然通过引用传递,因此它们可以被变异。 那么,如果我使用 stopArray = 组合来代替它,它是否也不能被突变? 不,因为它也会通过引用传递。我认为当数组或对象太深时,处理其值的唯一方法是执行深度克隆。使用 json stringify 进行 Json 解析是执行深度克隆的一种方式(尽管并非对所有情况都完美),因此在不知情的情况下,您可能已经完成了您能做的最好的事情之一 谢谢,我相信这将在整个项目中以数据格式的方式发生。我现在知道发生了什么! 感谢您的链接。我想我需要以不同的方式做到这一点。我向 JSON.stringify() 传递了一个非常大的对象数组,它出现了“RangeError: Invalid String Length”,这基本上意味着我的 JSON 字符串太长并且无法对其进行字符串化。我应该使用上面链接中的示例吗?看起来我可以使用 jQuery 或纯 javascript 来进行深度克隆。我还在网上读到你可以使用文件流媒体处理 JSON,但我没有文件流媒体的经验,我不确定它们是如何工作的。

以上是关于带有嵌套for循环的Javascript多维数组-无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Php多维数组与混合for和Foreach循环

多维javascript数组中的for循环

2018-06-15for与数组/for-in与数组/一维二维多维数组

如何从 C# 中的嵌套循环写入多维数组?

使用嵌套的每个循环构建多维数组?

javascript 数组对象与嵌套循环写法