Javascript排序的数组会改变窗口对象,但在遍历它时不会改变

Javascript sorted array mutates window object but not when iterate through it

本文关键字:改变 遍历 对象 排序 数组 窗口 Javascript      更新时间:2023-09-26

使用Python Django,我有一个视图,它将JSON返回到初始化全局JavaScript变量的模板,如下所示:

<script type="text/javascript">
    coordinates = {{ coordinates | safe}}
</script>

这些坐标有一个名为country的字段。

我使用对这些对象进行排序

coordinates.sort(sortByCountry); 

我的sortByCountry功能:

function sortByCountry(x, y) {
   return ((x.fields.country == y.fields.country) ?
            0 : ((x.fields.country > y.fields.country) ? 1 : -1 ));
}

所以当我运行时

coordinates.sort(sortByCountry); 

它返回对象的正确顺序。

但如果我循环通过坐标,它会循环通过,就好像它还没有排序一样在这里,我为每个国家校正一个新的数组,并将它们推入,使属于同一国家的所有坐标都在同一数组中。所有这些数组都嵌套在另一个名为countries的数组中。

        var countries = [];
        var counter = 0; // number of countries
        function sortByCountry(x, y){
                return ((x.fields.country == y.fields.country) ? 0 : ((x.fields.country > y.fields.country) ? 1 : -1 ));
        }
        function country_assignment(){
                coordinates.sort(sortByCountry); // ****This works returns a sorted coordinates list, can even do window.coordinates and get the sorted list
                countries.push(new Array());
                countries[counter].push(coordinates.pop());
                length = coordinates.length
                for( var l = 0;  l < length; l++){
                      //this loops through coordinates as if it was not sorted
                        if((countries[counter][0].fields.country == coordinates[0].fields.country)){

                                countries[counter].push(coordinates.pop());
                        } else {
                                countries.push(new Array());
                                counter = counter + 1;
                                countries[counter].push(coordinates.pop());

我试过

coordinates = coordinates.sort(sortByCountry); 

但这并不奏效。

JSON对象示例:

<script type="text/javascript">
        coordinates = [{"fields": {"latitude": 38.5512238, "country": "USA", "location": "802 D St, Davis, CA 95616, USA", "longitude": -121.7441921, "visited": true}, "model": "mapper.destination", "pk": 1}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 2}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 3}, {"fields": {"latitude": 13.7524008, "country": "Thailand", "location": "Na Phra Lan Rd, Khwaeng Phra Borom Maha Ratchawang, Khet Phra Nakhon, Krung Thep Maha Nakhon 10200, Thailand", "longitude": 100.490729, "visited": true}, "model": "mapper.destination", "pk": 4}, {"fields": {"latitude": 51.5073509, "country": "Britian", "location": "London, UK", "longitude": -0.1277583, "visited": true}, "model": "mapper.destination", "pk": 5}, {"fields": {"latitude": 51.1802192, "country": "Britian", "location": "Salisbury, Wiltshire SP4 7DE, UK", "longitude": -1.8270873, "visited": true}, "model": "mapper.destination", "pk": 6}, {"fields": {"latitude": 7.9519331, "country": "Thailand", "location": "Phuket, Thailand", "longitude": 98.33808839999999, "visited": true}, "model": "mapper.destination", "pk": 7}, {"fields": {"latitude": 25.7616798, "country": "USA", "location": "Miami, FL, USA", "longitude": -80.1917902, "visited": true}, "model": "mapper.destination", "pk": 8}]
        </script>

您的代码运行良好。坐标被分割成单独的数组,仍然进行排序。但是,它们是向后排序的,因为您从coordinates.pop()的末尾获取元素。

这是一个工作演示:

function sortByCountry(x, y){
    return x.fields.country == y.fields.country ? 0 : ( x.fields.country > y.fields.country ? 1 : -1 );
}
function country_assignment(coordinates) {
  
  dump(coordinates,'unsorted');
  
  coordinates.sort(sortByCountry);  
  
  dump(coordinates,'sorted');
  
  var countries = [];
  var counter = 0; // number of countries
  countries.push(new Array());
  countries[counter].push(coordinates.pop());
   
  while ( coordinates.length )
  {
    var c = coordinates.pop();
    if ( countries[counter][0].fields.country == c.fields.country )
      countries[counter].push(c);
    else {
      countries.push(new Array());
      counter ++;
      countries[counter].push(c);
    }
  }
  
  for ( var c in countries )
    dump(countries[c], c); 
}
function dump(coordinates,label) { 
  document.getElementById('debug').innerHTML += 
    "===DUMP=== " + label + "'n"
    + coordinates.map(function(f,i){return f.pk + ": "+f.fields.country;}).join("'n")
    +"'n'n";
}
country_assignment(
  [{"fields": {"latitude": 38.5512238, "country": "USA", "location": "802 D St, Davis, CA 95616, USA", "longitude": -121.7441921, "visited": true}, "model": "mapper.destination", "pk": 1}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 2}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 3}, {"fields": {"latitude": 13.7524008, "country": "Thailand", "location": "Na Phra Lan Rd, Khwaeng Phra Borom Maha Ratchawang, Khet Phra Nakhon, Krung Thep Maha Nakhon 10200, Thailand", "longitude": 100.490729, "visited": true}, "model": "mapper.destination", "pk": 4}, {"fields": {"latitude": 51.5073509, "country": "Britian", "location": "London, UK", "longitude": -0.1277583, "visited": true}, "model": "mapper.destination", "pk": 5}, {"fields": {"latitude": 51.1802192, "country": "Britian", "location": "Salisbury, Wiltshire SP4 7DE, UK", "longitude": -1.8270873, "visited": true}, "model": "mapper.destination", "pk": 6}, {"fields": {"latitude": 7.9519331, "country": "Thailand", "location": "Phuket, Thailand", "longitude": 98.33808839999999, "visited": true}, "model": "mapper.destination", "pk": 7}, {"fields": {"latitude": 25.7616798, "country": "USA", "location": "Miami, FL, USA", "longitude": -80.1917902, "visited": true}, "model": "mapper.destination", "pk": 8}]
);
<pre id='debug'></pre>

不过,有一种更简单的方法可以按国家划分坐标:使用对象。

  countries = {};
  while ( coordinates.length )
  {
    var c = coordinates.shift(), 
        f = c.fields.country;
    (countries[ f ] = countries[ f ] || [] ).push( c );
  }

function sortByCountry(x, y){
    return x.fields.country == y.fields.country ? 0 : ( x.fields.country > y.fields.country ? 1 : -1 );
}
function country_assignment(coordinates) {
  
  dump(coordinates,'unsorted');
  
  coordinates.sort(sortByCountry);  
  
  dump(coordinates,'sorted');
  
  var countries = {};  
  while ( coordinates.length )
  {
    var c = coordinates.shift(), 
        f = c.fields.country;
       
    (countries[ f ] = countries[ f ] || [] ).push( c );
  }
  
  for ( var c in countries )
    dump(countries[c], c); 
}
function dump(coordinates,label) { 
  document.getElementById('debug').innerHTML += 
    "===DUMP=== " + label + "'n"
    + coordinates.map(function(f,i){return f.pk + ": "+f.fields.country;}).join("'n")
    +"'n'n";
}
country_assignment(
  [{"fields": {"latitude": 38.5512238, "country": "USA", "location": "802 D St, Davis, CA 95616, USA", "longitude": -121.7441921, "visited": true}, "model": "mapper.destination", "pk": 1}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 2}, {"fields": {"latitude": 51.501009, "country": "Britian", "location": "London SW1A 1AA, UK", "longitude": -0.1415876, "visited": true}, "model": "mapper.destination", "pk": 3}, {"fields": {"latitude": 13.7524008, "country": "Thailand", "location": "Na Phra Lan Rd, Khwaeng Phra Borom Maha Ratchawang, Khet Phra Nakhon, Krung Thep Maha Nakhon 10200, Thailand", "longitude": 100.490729, "visited": true}, "model": "mapper.destination", "pk": 4}, {"fields": {"latitude": 51.5073509, "country": "Britian", "location": "London, UK", "longitude": -0.1277583, "visited": true}, "model": "mapper.destination", "pk": 5}, {"fields": {"latitude": 51.1802192, "country": "Britian", "location": "Salisbury, Wiltshire SP4 7DE, UK", "longitude": -1.8270873, "visited": true}, "model": "mapper.destination", "pk": 6}, {"fields": {"latitude": 7.9519331, "country": "Thailand", "location": "Phuket, Thailand", "longitude": 98.33808839999999, "visited": true}, "model": "mapper.destination", "pk": 7}, {"fields": {"latitude": 25.7616798, "country": "USA", "location": "Miami, FL, USA", "longitude": -80.1917902, "visited": true}, "model": "mapper.destination", "pk": 8}]
);
<pre id='debug'></pre>