JavaScript/JQuery - 对象属性值在循环访问它们时会发生变化

JavaScript/JQuery - Object property values are changing when looping through them

提问人:acc_it 提问时间:3/17/2023 最后编辑:acc_it 更新时间:3/17/2023 访问量:35

问:

我们正在尝试创建一种路由 (TSP) 算法,该算法遍历保存我们的车辆和行程信息的数据结构。

这一切都始于一个名为 acquireData 的 ASYNC 函数,该函数对我们自己的 API 进行 $.getJSON 调用,该 API 返回我们所有货车和行程以及所有(太多)信息的大型对象结构。这个异步函数循环遍历 API 对象返回,并用更少的数据构建一个全新的对象......

它返回新对象作为结果。

在底部,我们调用 async 函数,然后我们想在 .then() 中完成所有 TSP 求解。

在 .then() 中,我们记录 “data”(这是异步函数 acquireData() 返回的对象),一切看起来都很好。映像 aboce 是 console.log(data.trucks)。您可以看到所有 avilableAt 属性都有不同的日期/时间,除了那些没有旅行的属性。这是它应该的方式。到目前为止,一切都很好,数据完全符合我们的要求。

控制台.log(数据)

现在,我们开始遇到这个问题......

当我们尝试遍历此 data.trucks 时,availableAt 属性会失控。$.each(data.trucks, 函数(d, j){ 控制台.log(d, j.availableAt)})

一旦我们遍历它并显示 availableAt 属性,它们都会得到相同的日期/时间。比较两张图片,看看“Med 2”,你就会发现区别。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <title>Document</title>
</head>
<body>

  <script>

    function createDateObject(dateString, militaryTime) {
      if (typeof dateString === "boolean" || typeof militaryTime === "boolean" || militaryTime == ""){
        
        return "No Date"
      } else {
        const year = parseInt(dateString.slice(0, 4));
        const month = parseInt(dateString.slice(5, 7)) - 1;
        const day = parseInt(dateString.slice(8, 10));
        const hours = parseInt(militaryTime);
        const date = new Date(year, month, day, hours);
        return date;
      }
    }

    function formatCityState(city, state) {
      const formattedCity = city.replace(/ /g, '+');
      const formattedState = state.toUpperCase();
      return `${formattedCity},${formattedState}`;
    }

    function addSeconds(date, seconds) {
      var newDate = new Date(date.getTime() + seconds * 1000);
      return newDate;
    }

    function isBefore(date1, date2) {
      return date1.getTime() < date2.getTime();
    }

    function addHalfHourEvery4Hours(seconds) {
      var hours = seconds / 3600; // convert to hours
      var timeSlots = Math.floor(hours / 4); // calculate number of 4-hour time slots
      var extraHours = timeSlots * 0.5; // calculate extra half-hours
      var newHours = hours + extraHours; // add extra half-hours to original hours
      var newSeconds = newHours * 3600; // convert back to seconds
      return newSeconds;
    }

    const callGoogle = async(origin, destination) => {
      const params = encodeURIComponent('&origins=' + origin + '&destinations=' + destination);
      const grabData = await $.getJSON('no-cors.php?url=https://maps.googleapis.com/maps/api/distancematrix/json?' + params + '&key=xxxxxxx')
      return grabData;
      }

    async function acquireData() {
    const data = await new Promise((resolve, reject) => {
      $.getJSON('https://xxxxxxxxxx/xxxxx.php', function(data) {
      const newData = {
        // employees: {},
        trucks: {},
        trips: [],
        trips_unscheduled: []
      };
      $.each(data.trucks, function(j, k) {
        const truckObj = {
          trips: [],
          standing_location: k.name_value_list.location_c.value
        };
        if (j.includes('Med') || j == "") {
          if (k.trips) {
            for (let i = 0; i < k.trips.length; i++) {
              const tripDate = new Date(k.trips[i].name_value_list.transport_date_2_c.value);
              const now = new Date();
              const timeDiff = tripDate - now;
              const diffInHours = timeDiff / (1000 * 3600);
              const tripObj = {
                trip_id: k.trips[i].name_value_list.trip_id_c.value,
                dropoff_location: formatCityState(k.trips[i].name_value_list.arrival_city_c.value, k.trips[i].name_value_list.arrival_state_c.value),
                pickup_location: formatCityState(k.trips[i].name_value_list.departure_city_c.value, k.trips[i].name_value_list.deprature_state_c.value),
                pickup_time: createDateObject(k.trips[i].name_value_list.transport_date_2_c.value, k.trips[i].name_value_list.pick_up_time_c.value, k.trips[i].name_value_list.trip_id_c.value)
              };

              if (diffInHours > 48 && tripObj.pickup_time != "No Date") {
                newData.trips.push(tripObj);
              } else if (diffInHours < -45000 || tripObj.pickup_time == "No Date") {
                newData.trips_unscheduled.push(tripObj)
              } else {
                truckObj.trips.push(tripObj);
              }
            }
            //Generate availableAt for trucks with trips.
            if (truckObj.trips.length > 0) {
              var Corndogs = callGoogle(truckObj.trips[truckObj.trips.length - 1].pickup_location, truckObj.trips[truckObj.trips.length - 1].dropoff_location)
              .then((data) => {
                truckObj.availableAt =  addSeconds(truckObj.trips[truckObj.trips.length - 1].pickup_time ,addHalfHourEvery4Hours(data.rows[0].elements[0].duration.value))
                newData.trucks[j] = truckObj;
              })
            } 
          }
          //Generate availableAt for trucks with no trips. 
          let t = new Date()
          let tomorrow = new Date(t.setHours(t.getHours() + 24))
          truckObj.availableAt = tomorrow
          newData.trucks[j] = truckObj;
        }
      });
      resolve(newData);
    });
  });
  return data;
}

//now that we have our data built out the way we want it, we can loop through it and find the best truck for each trip.



//We will start by looping through each trip. 
  //Loop through each truck
    //if truck availableAt is before pickup time that means this truck is a possibility for current trip
      //calculate if the truck can make it to the trip pickup location in time
        //if it can lets save the travel time and distance in a variable as well as the good truck
          //loop through trips again and if there is a trip that is closer and has less sitting time lets replace 
          //continue looping through all the trucks ; everytime we find a truck that can make the trip but is less travel time and distance , save these details to the variable.
           
          
//Loop through each truck
  //Loop through each trip
    //if truck availableAt is before the tripPickUpTime then lets dive further
      //calculate travel time and distance from trucks drop off and avaialbleAt
        //if truck can make it in time
          //lets save that distance and time spent sitting into a variable and save that truck 
            //continue to compare it to other trucks nd if we find a lower distance/time
              //once we have looked through all the trucks  



acquireData().then((data) => {

  console.log(data)

  $.each(data.trucks, function(d, j){
    console.log(d, j.availableAt)
  })
  // console.log(data.trucks)

}).catch((error) => {
  console.error(error);
});



  </script>
  
</body>
</html>

JavaScript jQuery 对象 旅行推销员

评论

0赞 Kathara 3/17/2023
而不是尝试.还要注意,您设置日期的部分在 if 中,因此它将为所有人设置它。我建议将这 4 行放入该 if 语句的其他部分。if (k.trips)if (k.trips.length > 0)
0赞 acc_it 3/17/2023
@kathara 不幸的是,这并不能解决问题。老实说,我不知道错误是否在 acuireData 函数中。该函数按照我们想要的方式构建数据。
2赞 weirdgyn 3/17/2023
将日志作为代码转储到问题中,而不是链接到外部图像......

答: 暂无答案