Sort string in ascending order according to numeric value

Asked

Viewed 262 times

2

I have to insert numbers and sort in ascending order to display the result. But I’m not getting the order right. Here’s what happens:

Insert yourself for example 76,3,15,35 returns ordered as follows: 15,3,35,76.

// ordenar por ordem crescente os numeros inseridos.

const input1 = document.querySelector(".input1");
const btnConvert = document.querySelector(".btn-converter");

function sortNumbers(inputText) {
  let numArray = inputText.split(",");
  numArray.sort();

  document.getElementById("h").innerText = (` ${ numArray} `); 
  console.log(numArray)

  return  numArray;
}


btnConvert.addEventListener('click', function () {
  sortNumbers(input1.value);

});
<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Modelo</title>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
    <section class="container">
      <h1>Exercícios</h1>

      <label class="label"
        >INSERIR NÚMEROS 
        <input type="text"  class="input1" />
      </label>
      

      <button class="btn btn-converter">ORDENAR POR ORDEM CRESCENTE</button>

     
      <h2 class="total" id="h"></h2>
    </section>
    <script src="./main.js"></script>
  </body>
</html>

  • Okay, thanks :) However it would force me to always have two digits and not quite what I intended. Also, if for some strange reason I put 015,p. and, it would continue to order in the same way. But thanks for the tip anyway :)

  • 2

    Ana, putting zero left is gambiarra, forget it. It is simpler to convert to number as it works for any values (as indicated in the answers below)

  • okay, thank you :)

  • @hkotsubo, put zero left of hour with a digit is gambiarra too?

  • 1

    @Leocaracciolo In the case of hours, putting zero on the left is a matter of formatting/presentation, it is completely different from what is being done here. Putting a zero to the left on the string just to force a correct ordering I consider gambiarra, especially when there is a simpler and cleaner solution (convert the strings to number). Different problems, different solutions :-)

  • @hkotsubo, your understanding, note that the question is: Sort string in ascending javascript order, I read STRING or need to update my glasses?

  • @Leocaracciolo But we are ordering strings. Only the sorting criterion is to use the numeric value that the string represents, so I think it’s better to convert to number instead of adding zeros on the left. Because adding zeros is limited (if the string is '76,03,123456,35', for example, it no longer works, you would have to add more zeros to each number to work - something like '000076,000003,123456,000035'). And neither will I get the credit that '03' is a string other than '3'...

  • @hkotsubo, you are right, turn into numbers to sort is the best solution, put zeros would give a tremendous turn, take the length of the largest element of the array, put as many zeros as necessary, sort and return to the initial elements for presentation. But it would be a good exercise right?

Show 3 more comments

2 answers

6


When you do the split, the result is an array of strings.

Only that strings are compared lexicographically, that is, it takes into account their characters to define which is "larger" or "smaller". Even if these characters are digits, the numeric value they represent is not taken into account in the sort. Thus, the string '15' is "smaller" than the string '3' (in the sense that, in an ordering, the string '15' is placed before the string '3').

console.log('15' < '3'); // true

That’s why the string '15' was before the string '3'. To better understand why this is so, I suggest that read here.


Anyway, if you want to take into account the numerical value that the strings represent, I suggest turning them into numbers:

numArray.sort((a, b) => parseInt(a) - parseInt(b));

I used parseInt, because I make it clear that I am converting strings into numbers. And the idea of the callback is that it returns a negative number if a must come before b in ordination, a positive number if a should come later, or zero if it matters. That’s why I’m subtracting the values (because if the value of a is less than b, the result shall be negative, indicating that a should come earlier in the ordination).

Of course the code of another answer also works, but it’s because Javascript automatically coerces types in many cases (if I "subtract" 2 strings and they contain only digits, the conversion to number is done automatically).

But I prefer to be explicit and convert everything to number before doing the operations. I know that for this specific case it works, but it’s not always like this, even more if you mix numbers and strings - then create this habit of converting to the appropriate types only to then do the operations you need.


Remembering that parseInt only works with integers. If you also want to consider numbers with decimals (as long as the separator is the point), you can use parseFloat. Ex:

let s = '20,10.5,47.2,3';
let array = s.split(',');
array.sort((a, b) => parseFloat(a) - parseFloat(b));
console.log(array);

  • 2

    Excellent observation. I forgot to mention the importance of converting before making the necessary operation in order to avoid problems with the "weird" behavior of the JS

  • Got it, thank you so much for the tip :)

  • 2

    @Cmtecardeal In this specific case it is not so problematic because it is a "controlled environment" and we know that it would work "in all cases". But as a general rule, I always prefer to convert :-)

4

You could use numArray.sort((a,b) => {return a - b}); to order and not have this problem. You order by making a comparison values using the function (a,b) => {return a - b}, where:

  • If the return is less than 0, then b is greater than a, soon a comes before b;
  • If the return is greater than 0, then b is less than a, soon b comes before a;
  • If the return is equal to 0, then b is equal to a;

See how it looks:

// ordenar por ordem crescente os numeros inseridos.

const input1 = document.querySelector(".input1");
const btnConvert = document.querySelector(".btn-converter");

function sortNumbers(inputText) {
  let numArray = inputText.split(",");
  numArray.sort((a,b) => {return a - b});

  document.getElementById("h").innerText = (` ${ numArray} `); 
  console.log(numArray)

  return  numArray;
}


btnConvert.addEventListener('click', function () {
  sortNumbers(input1.value);

});
<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Modelo</title>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
    <section class="container">
      <h1>Exercícios</h1>

      <label class="label"
        >INSERIR NÚMEROS 
        <input type="text"  class="input1" />
      </label>
      

      <button class="btn btn-converter">ORDENAR POR ORDEM CRESCENTE</button>

     
      <h2 class="total" id="h"></h2>
    </section>
    <script src="./main.js"></script>
  </body>
</html>

Would that be the answer to 76,3,15,35:

[
  "3",
  "15",
  "35",
  "76"
]

TIP

To leave in descending order, just reverse the return of the comparison function:

numArray.sort((a,b) => {return b - a});
  • 1

    Thank you :) I had tried to do it this way, but I invented it and it was simple. thanks, it was solved :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.