When iterating through it, a sorted array in Javascript mutates the window object, but not in any

I am working with Python Django to create a view that returns JSON data to a template. In this template, I initialize a global JavaScript variable like so:

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

These coordinates contain a field called country.

To organize these objects, I use the following sorting method:

coordinates.sort(sortByCountry); 

This is my custom sortByCountry function:

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

When I run

coordinates.sort(sortByCountry); 

, it correctly orders the objects.

However, when I loop through the coordinates array, it seems as if the sorting did not take effect. For each country, I create a new array and group all coordinates belonging to that country together in that array. All of these arrays are nested within another array named 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());

I have attempted

coordinates = coordinates.sort(sortByCountry); 

But this approach also does not produce the desired result.

Here is an example of the JSON objects structure:

<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...
        </script>

Answer №1

Your code is functioning properly. The coordinates have been separated into distinct arrays, but they are sorted in reverse order due to using `coordinates.pop()` to extract elements from the end.

Check out this working demo:

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>

There is an alternative method to separate the coordinates by country using objects instead:

  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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Rendering a custom Vue 3 component as a string and then passing it to another component as a prop

Hey there coding mates! Currently diving into Vue 3 and the composition API with setup. I've been crafting a custom "Table" component to display... well, tables. It requires a prop named "data", which is an array of objects (representing rows) conta ...

Utilizing JSON strings within an onclick function

Hey there, currently I am working on sending an encoded JSON through the onclick attribute. However, I am facing a challenge because the JSON contains strings with a lot of apostrophes and quotes which end up closing the quotes in the onclick attribute. Up ...

Link the selector and assign it with its specific value

Greetings, I am a newcomer to React Native and I am currently using Native Base to develop a mobile application. I am in the process of creating a reservation page where I need to implement two Picker components displaying the current day and the next one ...

The functionality of nested dynamic routing in the API is experiencing issues

Looking to extract product details from a specific category of products? My folder structure appears as follows: https://i.stack.imgur.com/1UCy3.png In "productId/index.jsx" => This snippet is utilized to retrieve individual product details: ...

Using PHP and JavaScript to enhance functionality around a hyperlink

I am trying to incorporate a small piece of Javascript on my website to ensure user confirmation. While I have successfully used the 'onclick' function with buttons, I am facing difficulty implementing it on a link. Here is the link in question: ...

Prevent ng-repeat from rendering the contents of my div

Currently, I am in the process of modifying a website for which I need AngularJS. I am trying to use the ng-repeat command to display some documentation on the site. However, whenever I add the ng-repeat within a div, it seems to "destroy" the layout and I ...

Leverage recursion for code optimization

I'm currently working on optimizing a function that retrieves JSON data stored in localStorage using dot notation. The get() function provided below is functional, but it feels verbose and limited in its current state. I believe there's room for ...

The application appears to be overloaded with tasks on its main thread, potentially causing errors

I am currently in the process of developing an app for user login and registration. The app relies on receiving a JSON response from a webservice to interact with the database. However, during the registration process, I encountered the following error mes ...

Guide on adjusting shipping costs in Stripe based on the customer's address using NodeJS

Utilizing Stripe's Checkout API, I am seeking to provide international shipping options with varying costs based on the country selected at checkout. Is there a method within Checkout that allows me to dynamically adjust shipping costs based on the us ...

Issue with AJAX MVC HTML: jQuery value is not blocking API call

Upon clicking a button, I am triggering a web API call using AJAX. My form is utilizing JqueryVal for form validations based on my viewmodel data annotations. The issue I am facing is that when I click the "Listo" button in my form, it executes the API ca ...

Getting data from Twilio Autopilot using PHP is not as complicated as it may seem

Hey everyone! I've encountered an issue with my PHP code that needs to receive some JSON (x-www-form-urlencoded) data from a Twilio Autopilot redirect. This is the code I'm currently using: $data = file_get_contents('php://input'); H ...

Can a ListItem attribute be generated?

In the realm of Material UI, you can find a detailed showcase of ListItem at http://www.material-ui.com/#/components/list The appearance of a nested ListItem is demonstrated below: <ListItem value={1} primaryText="Brendan Lim" leftAvatar={ ...

Unable to "serialize" geoJSON information

While working with Leaflet JavaScript, I am attempting to retrieve data directly from GeoServer using an Ajax link. To display it nicely in a DataTables table, I need to convert it into JSON format as per DataTables instructions. However, I keep encounteri ...

Converting a JavaScript array to JSON format

I'm struggling with JavaScript and need some help. I have two arrays that I want to convert into a data series, but I'm not sure how. Here are the arrays: colors = ['red', 'green', 'blue']; values = [20, 50, 10 ...

I am having trouble passing a variable into the AJAX URL using JavaScript

Currently, I am attempting to remove an item from mongodb. However, I am encountering difficulty passing the id into the URL through the ajax call. Below is my code: $(".delete-item").on('click', function(e, id) { var deleteName = ...

I require the variable to be accessible from all corners

Is there a way to access the variable "finalPrice" in a different function? I'm trying to achieve this and could use some guidance. function available(id){ $.ajax({ method:"GET", }).done(function(data){ for( ...

Dealing with functions that may not consistently return a promise

When dealing with a situation where a function does not always return a promise, how can it be best handled? The complexity of my current code prevents me from providing a detailed explanation, but essentially, the issue involves checking a condition and t ...

What is the best method for transferring states between components?

When it comes to React JS, I am a beginner looking to develop a ToDo list application. In my project, I have the main page App.js, where I created the component MainBlock. This MainBlock component structures the layout into left and right sides. On the rig ...

There seems to be some odd behavior with the setIcon function in the Google Maps API

Initially, the marker.setIcon method didn't work for me. Upon inspecting the browser console, I encountered this message: To troubleshoot, I attempted using markerObject.icon = "/Content/img/icon_critical.svg", although it should have been "/Content/ ...

``Is it possible to adjust the style of an HTML element based on the style of another element?

Within my web application, I am dynamically changing the style of an HTML element using JavaScript. Below is the code snippet: function layout() { if(document.getElementById('sh1').getAttribute('src') == "abc.png") { docum ...