如何使用我的数据转义$ .each循环?

时间:2017-07-02 09:39:21

标签: javascript arrays sorting for-loop

我正在进行Json调用以检索包含每个位置信息详细信息的位置列表。经度和纬度都包含在此信息中。

我正在使用Google的距离矩阵api来获取与网址中作为查询提供的坐标的距离。

我认为最合乎逻辑的方法是遍历各个位置并比较每个位置的搜索和位置坐标。我将距离矩阵调用返回的一些信息附加到我的数据数组中。

除了从距离矩阵返回的数据仅可用于距离矩阵的返回函数之外,这种方法很好。我将有用数据从距离矩阵返回函数传递到矩阵返回函数之外的函数,但仍在$ .each循环内。这样做就像是朝着解决我的问题迈出了一步,但我被卡住了。

我需要使用原始数据,但附加距离矩阵数据,以便我可以按距离对数据中的项目进行排序并输出。我不认为排序函数在$ .each循环中运行良好,所以我需要打破循环,并附加完整的数据版本。至少我认为。任何帮助,将不胜感激。

var ltlg = [];
var sLat = parseFloat(35.2219971);
var sLng = parseFloat(-101.83129689999998);
var sLatLng = {lat: sLat, lng: sLng};

var locLat;
var locLng;
var locLatLng = [];

$.getJSON("file.json",function(data){

    if(sLat && sLng) {

        $.each(data, function(x, y){

            locLat = data[x].Address.Location.Latitude;
            locLng = data[x].Address.Location.Longitude;

            //locLatLng.push({lat: locLat, lng: locLng});

            var service = new google.maps.DistanceMatrixService;

            service.getDistanceMatrix({
                origins: [sLatLng],
                destinations: [{lat: locLat, lng: locLng}],
                travelMode: 'DRIVING',
                unitSystem: google.maps.UnitSystem.IMPERIAL,
                avoidHighways: false,
                avoidTolls: false
            }, function(response, status) {
                if (status !== 'OK') {          
                    console.log('status is ' + status);        
                } else {
                    var distance = response.rows[0].elements[0].distance.value;
                    var miles = response.rows[0].elements[0].distance.text;
                    var time = response.rows[0].elements[0].duration.text;

                    addData(distance, miles, time);
                }

            });

            function addData(distance, miles, time) {
                data[x]["distance"] = distance;
                data[x]["miles"] = miles;
                data[x]["time"] = time;
            }

        });

        console.log(JSON.stringify(data));

    } else {
        console.log('no query');
    }

});

我用代码片段的静态lat lng替换了查询变量。

2 个答案:

答案 0 :(得分:0)

您可能希望实现全局回调,例如:

function loaddata(callback){
  var counter=0;
  data.forEach(function(y,x){
    //get data
   function addData(distance, miles, time) {
     data[x]["distance"] = distance;
     data[x]["miles"] = miles; 
     data[x]["time"] = time;
     if(++counter==data.length){
      callback(data);
     }
   }
  });
}

所以你可以这样做:

loaddata(function(data){
 console.log(data);
});

现在数据包含距离,里程和时间。

答案 1 :(得分:0)

@Jonasw提供的答案是不必要的复杂,并且因为每次迭代都声明了一个新的addData(),并且初始化了一个完全没有意义的counter,这会占用大量的内存,用更聪明的方法来保护。由于您对每个数据点都有异步回调,并且您希望完全依赖所有数据点,因此最有意义的方法将使用Promise.all()

var sLat = 35.2219971;
var sLng = -101.83129689999998;
var sLatLng = {
  lat: sLat,
  lng: sLng
};

var service = new google.maps.DistanceMatrixService;

function serviceCallback(value, resolve, response, status) {
  if (status !== 'OK') {
    console.log('status is ' + status);

    reject(status);
  } else {
    value.distance = response.rows[0].elements[0].distance.value;
    value.miles = response.rows[0].elements[0].distance.text;
    value.time = response.rows[0].elements[0].duration.text;

    resolve(value);
  }
}

function promiseExecutor(value, resolve, reject) {
  service.getDistanceMatrix({
    origins: [sLatLng],
    destinations: [{
      lat: value.Address.Location.Latitude,
      lng: value.Address.Location.Longitude
    }],
    travelMode: 'DRIVING',
    unitSystem: google.maps.UnitSystem.IMPERIAL,
    avoidHighways: false,
    avoidTolls: false
  }, serviceCallback.bind(null, value, resolve));
}

$.getJSON("file.json", function (data) {
  if (![sLat, sLng].some(isNaN)) {
    Promise.all(data.map(function (value) {
      return new Promise(promiseExecutor.bind(null, value));
    })).then(function (data) {
      console.log(JSON.stringify(data, null, 2));
    });
  } else {
    console.log('no query');
  }
});

但是,当您能够同时为每个数据点创建一个数据点时,我发现您正在请求每个数据点,因此为了节省更多资源,您可以尝试这样的事情:

var sLat = 35.2219971;
var sLng = -101.83129689999998;
var sLatLng = {
  lat: sLat,
  lng: sLng
};

var service = new google.maps.DistanceMatrixService;

$.getJSON("file.json", function (data) {
  if (![sLat, sLng].some(isNaN)) {
    service.getDistanceMatrix({
      origins: [sLatLng],
      destinations: data.map(function (value) {
        return {
          lat: value.Address.Location.Latitude,
          lng: value.Address.Location.Longitude
        };
      }),
      travelMode: 'DRIVING',
      unitSystem: google.maps.UnitSystem.IMPERIAL,
      avoidHighways: false,
      avoidTolls: false
    }, function (response, status) {
      if (status !== 'OK') {
        console.log('status is ' + status);
      } else {
        response.rows[0].elements.forEach(function (element, index) {
          if (element.status === 'OK') {
            data[index].distance = element.distance.value;
            data[index].miles = element.distance.text;
            data[index].time = element.duration.text;
          }
        });

        console.log(JSON.stringify(data, null, 2));
      }
    });
  } else {
    console.log('no query');
  }
});