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

Conceal the message "Table does not contain any data" if data exists in the table

This table is populated with data retrieved via JSON. Here is the structure: <table id="tblClaimSearch" class="display responsive nowrap" cellspacing="0" width="100%"> <thead> <tr> <th><input type="checkbox" ...

Outdated jQuery script no longer functioning (Wordpress)

I recently updated a WordPress site to Version 5.7.2 and now two of the custom Metaboxes are not functioning as expected. The issue seems to be related to the outdated jQuery version used by the Metaboxes. To address this problem, I installed a Plugin cal ...

Working with a list in Json.Decode.Pipeline in Elm version 0.18

Within my code, I have a type alias that includes a nested list. I am looking to use Json.Decode.Pipeline to parse this data structure. import Json.Decode as Decode exposing (..) import Json.Encode as Encode exposing (..) import Json.Decode.Pipeline as Pi ...

The (ReactJS + Redux) form fails to load when the /new segment is appended to the URL

I'm currently working on a project using React, Redux, and Rails. I've encountered an issue with loading the form. In my App.js file, I have set up a Router that defines the routes. import React, { Component } from 'react'; import { Br ...

Information submitted through an ajax request does not get saved in the $_POST array

After successfully executing an AJAX request using GET, I decided to try POST this time. However, when attempting to send data, a baffling error message appeared in the console - NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED: 'JavaScript component does ...

Working with jQuery: Retrieving the ID of an element that is generated dynamically

Looking for some guidance: I'm working on dynamically creating a table based on the response from an AJAX call. The table includes headers and rows, with new rows added using the "after" function. However, I'm facing an issue with accessing the ...

Having trouble making the menu stay at the top of the page in IE7

Check out the demo here: http://jsfiddle.net/auMd5/ I'm looking to have the blue menu bar stay fixed to the top of the page as you scroll past it, and then return to its original position when scrolling back up. This functionality works in all brows ...

React Prop Local Modal Redux

Just diving into the world of React and Redux, and I'm a bit lost on how to effectively utilize both local properties and redux properties simultaneously. After trying different approaches without success, I'm reaching out for guidance. My goal i ...

Including input within a component causes the input to capture all click events

I've been working on a project where I need to create a color picker component. When you click on the .swatch element, a popover opens up with a .cover div that covers the whole screen. Clicking on the cover closes the popover, following standard beha ...

AngularJS checkbox validation requires a minimum of two checkboxes to be selected

When using AngularJS, I am looking to create a validation rule where a minimum of 2 checkboxes must be checked for the input to be considered valid. Here is what I have attempted: <div ng-repeat="item in items"> <label><input type="chec ...

Check the Full Calendar to see if any events are scheduled for today

I have a group of users who need to save their availability. Currently, I am utilizing Full Calendar and looking for a way to prevent them from adding the same event multiple times on a single day. My tech stack includes VueJs and all events are stored in ...

Challenges with Tab navigation in React and Ionic 5

I am facing a challenge with getting the tabs navigation to function correctly. Here is my current code: App.tsx: const App: React.FC = () => <IonApp> <IonReactRouter> <IonRouterOutlet id="main"> < ...

Restore the initial content of the div element

Currently, I am utilizing the .hide() and .show() functions to toggle the visibility of my page contents. Additionally, I am using the .HTML() function to change the elements inside a specific div. $('#wrap').html(' <span id="t-image"> ...

Tips for notifying a user about leaving a page without saving their information

I created a small table where users can input product names and numbers. My question is, how can I notify the user if they try to leave the page without saving the entered information? <form action="index.php" method="post"> <input type="text" ...

Issues encountered with AngularJS directive binding inner content not functioning as expected

I am currently developing a feature toggle directive, which requires a check to be performed in order to display content if the check is successful. I want the directive to replace itself with its content without creating a new child scope (so I'm try ...

How do I test Pinia by calling one method that in turn calls another method, and checking how many times it has been called

As I embark on my journey with Vue 3 and Pinia, a particular question has been lingering in my mind without a concrete answer thus far. Let's delve into the crux of the matter... Here's an example of the store I am working with: import { ref, co ...

Restrict HTML Elements Based on Their Size

I have a text file with a substantial amount of content that I need to display in an HTML format. The challenge is that I only want to show a portion of the text on the screen, but I am unsure of the exact amount that needs to be displayed. What I do know ...

Using Dependency Injection with JavaScriptConverter.Deserialize

My project requires a unique blend of dependency injection and JSON usage for its public API. This has brought me to the realization that I need a custom JavaScriptConverter. Currently, the Deserialize method in my JavaScriptConverter looks like this: pu ...

Tips on utilizing Jquery to extract an array containing UL, LI, and input elements

I am currently working with five ul lists, each of which may contain an input element. For example: <form id="testForm"> <ul id="1"> <li>TEST</li> <li>Gender: <select id="gender" name="gender"> ...

Working with variables passed from Node.js in Jade processing

Currently, I have a situation where my script is sending a matrix that looks like this: [[1,2,3,4], [7,6,5,4], [2,3,4,5]]. After sending it using res.send(JSON.stringify(dataArray)); and viewing it in jade with h1#results, I can see that the format appears ...