Why does the Javascript sorting algorithm fail to properly sort based on the sum of digits, even when using a comparison function?

I implemented a function that sorts an array of integers based on the sum of their digits. If two numbers have equal digit sums, then it sorts by the numerical values. Here is the function:

function digitSum(n){
    var result = 0;
    while (n) {
        result += n % 10;
        n /= 10;
    }
    return result;
}

function digitalSumSort(arr) {
    arr.sort(function(x, y) {
        return digitSum(x) != digitSum(y) ? digitSum(x) - digitSum(y) : x - y;
    });
    return arr;
}

While this function works correctly most of the time, it failed with the following test data:

Input: [100, 22, 4, 11, 31, 103]

Output: [100, 11, 31, 4, 22, 103]

Expected Output: [100, 11, 4, 22, 31, 103]

I am struggling to identify why it behaves unexpectedly in this case and how I can rectify it.

Note: It is crucial to keep the code as concise as possible.

Edit: Although this question has been resolved previously, I encountered the same issue recently which prompted me to revisit it. Is there a technique to ensure that a var behaves like an integer instead of a double when assigned a numeric value? I am aware of using floor for this purpose, but sometimes I prefer standard integer operations over double ones (due to potential performance advantages or other reasons).

Answer №1

The issue primarily lies with the function s, as it continues to loop and gather values when 'g' is a fraction.

Instead of computing values while sorting, consider utilizing a technique known as the Schwartzian transform, also referred to as decorate-sort-undecorate. This method involves creating an array with computed values for sorting, sorting the array, and then mapping back to the original values.

function s(g) {
  var r = 0;
  while (g) r += g % 10, g = Math.floor(g/10); // round down 'g' to avoid redundant loops for fractions
  return r;
}

function digitalSumSort(a) {
  return a
    .map(function(n) { // create an array with original and computed values
      return [s(n), n];
    })
    .sort(function(a, b) {
      return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]; // sort based on computed or original values
    })
    .map(function(n) { // get back an array of the original values
      return n[1];
    });
}

console.log(digitalSumSort([100, 22, 4, 11, 31, 103])); // [100, 11, 4, 22, 31, 103]

Answer №2

Shoutout to @JJJ for the helpful tip: try printing out the result of s() using console.log(s(22)) and similar.

It finally dawned on me that the function s() was producing incorrect outputs.

Here's the corrected code:

function s(g){
    var r=0;
    while(g) r += g % 10, g = Math.floor(g / 10);
    return r;
}

function digitalSumSort(a) {
    a.sort(function(x, y){
        return s(x) != s(y) ? s(x) - s(y) : x - y;
    });
    return a;
}

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

Express route encountered an error with an undefined value

Here's the method declaration: exports.postRedisValue = function(req,res) { let keyRedis = req.body.key; let valueRedis = req.body.value; console.log(keyRedis); //displays as undefined if(keyRedis && valueRedis){ ...

What could be causing the div to not respond to ngAnimate?

Recently, I encountered an issue with adding animations to a list of <div>'s in my webapp. After incorporating ngAnimate into the app.js file and including ng-animate="'animate'" in the <div>, I was disappointed to find that the ...

React-native: Project encountered errors after the Catalina update

After upgrading my Mac OS from High Sierra to Catalina, I encountered an issue when trying to run my project. I followed the steps of running the command react-native init, pod install in the ios directory, and then attempted to run the iOS code using Xco ...

Node JS post route experiencing issues with updating variables within function

I'm in the process of developing an online salon booking system. My goal is to prevent a booking from being made if the salon already has an appointment booked for that day and if the user attempting to make the booking also has an appointment booked ...

HTML integration of JavaScript not working as expected

My experience with separating files in HTML and JS has been positive - everything works smoothly when I link the JS file to the HTML. However, an issue arises when I decide to include the JS code directly within <script> tags in the HTML itself. The ...

I am currently grappling with a JavaScript mouse over event and encountering some difficulties

I am looking to dynamically change the background image of my body div whenever a link is hovered over. Here is a snippet of my code: JAVASCRIPT: var i = 0, anchors = document.querySelectorAll("zoom"), background = document.getElementById("body") ...

"Proceeding without waiting for resolution from a Promise's `.then`

I am currently integrating Google Identity Services for login on my website. I am facing an issue where the .then function is being executed before the Promise returned by the async function is resolved. I have temporarily used setTimeout to manage this, b ...

Ways to verify AJAX Response String when data format is specified as JSON

When using AJAX to retrieve JSON data from a webpage, it's essential to set the responseType to json. If the data processing is successful, a valid JSON string is returned, which works perfectly. However, if there's an error on the webpage, inst ...

Twitter posting unsuccessful: Issue encountered - Your current access is restricted to certain Twitter API v2 endpoints along with limited v1.1 endpoints like media post and oauth

My JavaScript app uses NPM Twit to post on Twitter. Suddenly, my bot stopped working with no explanation. It turns out that Twitter required me to switch to their new free tier and I had to delete all content from my Twitter Dev account and recreate my pro ...

Order of Execution

I am facing an issue with the order of execution while trying to retrieve values from my WebApi for input validation. It appears that the asynchronous nature of the get operation is causing this discrepancy in execution order. I believe the asynchronous b ...

Tips for concealing a source element when it is hidden

Even with the use of display: none, the contents of the element remain visible in the source code. Could techniques such as JavaScript, PHP, or any other method be employed to avoid this issue? ...

Which programming language is more suitable for developing a chat website - PHP or JSP?

My goal is to create a web-based chat application similar to Yahoo's, utilizing JSP/PHP with AJAX. I'm debating between using JSP or PHP for this project and looking for the advantages and disadvantages of each. Which do you think would be bette ...

How can I effectively retrieve and utilize data from two arrays passed through a jQuery .post() method in PHP?

I am currently using jQuery .post() method to send arrays like this: 'cleanedLinkStructureArray[]': cleanedLinkStructureArray, 'cleanedPermaLinkArray[]': cleanedPermaLinkArray The content of these arrays is as follows: cleanedPermaLin ...

Exploring the Relationship of std::array, std::vector, and the std::copy Function

I'm attempting to transfer a std::array into a std::vector using std::copy. The prototype of std::copy according to cppReference is: std::copy(InputIt first, InputIt last, OutputIt d_first) , where OutputIt d_first represents the start of the destina ...

Using the State Hook in React to modify variables via input boxes

Currently, I am facing an issue with implementing a React script to update a variable by setting it equal to the user input. The input should be a 10-digit number, however, I'm struggling to actually update the variable. Below is the code snippet I h ...

Changing the class name in HTML depending on the size of the screen

I'm attempting to dynamically change the class tag's name when a user visits the page based on the screen size. Below is the code snippet I've used: <!DOCTYPE html> <html> <body onload="changeClass()"> <section class=" ...

Arrange the months in a consecutive order

I need help sorting an array of months represented by numbers 1-12 in a way that creates the largest continuing sequence. For example: array(1,2,3): The sequence is already complete: Jan-Mar array(1,2,11,12): This could represent a continuous sequence ...

The alert message fails to show up after the initial click on the close button

Whenever I click the x button to dismiss an alert message (indicating wrong data input in a form), the next time the user checks the form and enters incorrect data again, the alert message does not reappear after closing the x button. Any suggestions on ho ...

Obtain HTML controls in the code-behind of an ASP.NET application

Is it possible to access HTML changes made with JavaScript in ASP.NET code behind? I came across some dhtml "drag and drop" code online (), but I'm struggling to access the updated controls in my code behind after moving items between lists. I attem ...

Adding an event listener to detect left or right mouse clicks - using onclick doesn't capture right clicks

I'm currently in the process of applying for an Internship through this Internship Link One thing that caught my attention right away is the issue with uploading or pasting a cover letter. When attempting to upload or paste a cover letter, it redirec ...