Home > Net >  Javascript Multi-Dimensional Array with nested for Loop - Not working right
Javascript Multi-Dimensional Array with nested for Loop - Not working right

Time:12-16

I have a multidimensional array that I am looping through with two for loops. If some criteria is met, i.e the value of j is 0 then I want to run code to insert an additional field into the array. If j is above 0 I want to run a function and then apply this update to the array.

My problem is this. The looping seems to work great, but it seems to be updating the wrong section of the array at some point and I am unsure why. I have provided a test dataset and the code that I am referring to. The value when j=0 for "legCrowFliesDistance" should be equal to "distanceFromKage" based on my code in the "calcCrowFliesTripMiles" function and it is not. I'm not sure what is going on here but I cant seem to figure it out.

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; }

Edit: Here is another dataset to test, its slightly smaller and is a minimalist version of the actual data I am pulling. The results I'm getting when I used the testArray and using my actual array are different. when I create the test array, I copy the actual data from the console, remove some attribute fields that are not used in this function and then assign the data to an array. I have no idea why the results would be different between the two because the data looks exactly the same, excluding the additional attribute fields.

Data:

[
          [
              {
                  "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,
                  
              }
          ]
      ]
        

Results when using 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
        }
    ]
]

Results when using actual data (removed most attribute fields):

[
    [
        {
            "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
        }
    ]
]

CodePudding user response:

I've taken a look at your code, and for me I have got the first element of each array inside the parent array to have the same value as legCrowFliesDistance. I found that you were trying to re-declare the variables lat1 and lat2 in your calcCrow function. I renamed these to lat1rad and lat2rad and it seems to be working as you described. I'm not sure if this is the fix you're looking for but I don't have another output to compare it with.

This is the code:

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;
}

Hope this helps!

Edit:

This is what I get in the console:

[
  [
    {
      "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
    }
  ]
]

CodePudding user response:

After a ton of troubleshooting, I came up with a solution that works, but I have no idea why it works, just that it does. I convert my data to JSON with JSON.stringify and then parse it with JSON.parse and then the functions that were not working before work correctly. This is the only line of code I changed.

Original Code:

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

New Code:

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