5

I am trying to order this array in Javascript

arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]; 

And i want that the array is showed like this:

["3", "4", "10", "23", "42", "63", "ABC", "adidas", "ax", "ba", "mof", ")", "["] 

Considering the symbols ")" , "[" too.

The order that i want to be the array is:

  1. the numbers from minor to mayor
  2. then the words, the capital letter doesn't matter.
  3. Finally, the symbols.

I know that i must use sort(), but the problem is i can't order the array with the symbols, i have that problem

I am using that code to show the array and the ordered array in HTML

var arr, text, larr, i; arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]; larr = arr.length; text = "<ul>"; for (i = 0; i < larr; i++) { text += "<li>" + arr[i] + "</li>"; } text += "</ul>"; document.getElementById("arrayin").innerHTML = text; console.log(arr); var arror,textor, larror, j; arror = arr.sort(); larror = arror.length; textor = "<ul>"; for (j = 0; j < larror; j++) { textor += "<li>" + arror[j] + "</li>"; } textor += "</ul>"; console.log(arror); document.getElementById("Oarray").innerHTML = textor; 

My final question is how can i order the array with the numbers, letters and symbols

1
  • You'll need to create a custom sort function and pass it as arr.sort(sortFunction);. which takes 2 parameters. Inside the sort function, you'll need to first compare if both parameters are both numberlike, if they are, return the appropriate integer for their comparison (with number-like strings compared as numbers) and if they are not, then set both to uppercase and compare them lexicographically. Commented Oct 11, 2018 at 17:28

5 Answers 5

4

As you guessed you do have to use the sort method and pass in a compare function. In order to get the order you are looking for the following checks will work. Full working example on jsfiddle here - https://jsfiddle.net/aczhyk8j/1/

function compare(a, b) { // check for numberhood const numA = !isNaN(a); const numB = !isNaN(b); if (numA && numB) { return Number(a) - Number(b); } if (numA) return -1; if (numB) return 1; // check for wordhood const wordA = /^[a-zA-Z]+$/.test(a); const wordB = /^[a-zA-Z]+$/.test(b); if (wordA && wordB) { return a.localeCompare(b); } if (wordA) return -1; if (wordB) return 1; return 1; // or whatever logic to sort within non-alphanumeric values } // Now, use it in your sort method call. let arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]; arr.sort(compare); console.log(arr);

Sign up to request clarification or add additional context in comments.

2 Comments

Chinese words are considered as special symbols, will you make change to considered as alphabets
Can you please tell me how to tweak the above code if I want the output in the below format; [ "3", "4", "10", "23", "42", "63", "A", "B", C", "M", "a", "b", "c", "m", Adidas", "ax", "ba", "mof", ")", "[" ] . I mean number first, then just A to Z letters, then words and symbols. Thanks in advance
3

Using a custom sort() function you can achieve what you want.

It's not easy and may need some "hacky" way to separete 'symbols' from normal characters. I used this "hacky" way, but maybe someone can help with some regEx or other way.

My hack is to have an array of possible symbols and then inside the sort(), when one of the itens that is being compared is equal to one of the symbols, temporary change it to a string "zzzzzzz" this will probably make it go to the last position since the sort is from "a" to "z".

The sort() function needs to return 1, 0 or -1, so it is what the custom compare() function do. It first see if the comparing words are valid numbers, if yes, then compare to see which one comes first. Then if it is not numbers, compare it as strings in upperCase, since you said that case doesn't matter (using the normal lexographical sort)

Test the below code to see if it is what you need.

var arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"] var symbols = "()[]{}!@#$%¨&*-_=+".split(""); function compare(array){ array.sort((a,b) => { if (symbols.indexOf(a) > -1) a = "zzzzzzz" if (symbols.indexOf(b) > -1) b = "zzzzzzz" if (!isNaN(Number(a)) && !isNaN(Number(b))){ if (Number(a) > Number(b)){ return 1; }else if(Number(a) < Number(b)){ return -1; }else{ return 0; } }else{ if (a.toUpperCase() > b.toUpperCase()){ return 1; }else if(a.toUpperCase() < b.toUpperCase()){ return -1; }else{ return 0; } } }) return array; } console.log(compare(arr))

Comments

3

I used sort with this custom comparator function. Recall that the comparator should return a positive number if a should come before b, a negative number if b should come before a, and 0 if the elements are equal under the ordering.

let array = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC", "abc"]; array.sort((a, b) => { const aStr = String(a).toLowerCase(); const bStr = String(b).toLowerCase(); // Alphanumeric elements always come before non-alphanumeric elements const aIsAlphanumeric = isAlphanumeric(aStr); const bIsAlphanumeric = isAlphanumeric(bStr); if (aIsAlphanumeric && !bIsAlphanumeric) { return -1; } else if (bIsAlphanumeric && !aIsAlphanumeric) { return 1; } // Numerical elements always come before alphabetic elements const aNum = Number(a); const bNum = Number(b); // If both are numerical, sort in the usual fashion (smaller goes first) if (aNum && bNum) { return aNum - bNum; // If a is numerical but b isn't, put a first. } else if (aNum) { return -1; // If b is numerical but a isn't, put b first. } else if (bNum) { return 1; } // In all other cases, default to usual sort order. return aStr.localeCompare(bStr); }); console.log(array); function isAlphanumeric(str) { var code, i, len; for (i = 0, len = str.length; i < len; i++) { code = str.charCodeAt(i); if (!(code > 47 && code < 58) && // numeric (0-9) !(code > 64 && code < 91) && // upper alpha (A-Z) !(code > 96 && code < 123)) { // lower alpha (a-z) return false; } } return true; }

Note: The isAlphanumeric function is taken from this answer.

Comments

0

You can override the default sort by passing compare function.

function compare(a, b) { // Check if number, and if number, parse and compare. // Check other logics } arr.sort(compare); 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters

Comments

0

I use this to make complex, multiple comparison sorts easy. Pretty easy to adapt, probably useful for anyone looking at this question:

const strings = [ 'Match but long text should be sorted down', 'This would go even further below', 'And this even more since it\'s longer than we like', 'Also below', '0 goes way down', '1 below it', '$ all the way down', 'á and match for top', 'á should go below ma-tches', 'Á this below á', 'Zee match for second row' ]; const matchText = 'match'; const sortBelowLen = 40; // List of comparison functions. Should return -1 if a goes before b, 1 if after, 0 if equal. const sortTests = [ // Contains matchText (ignore case) (a, b) => sortTest(a, b, (x) => x.toLowerCase().indexOf(matchText) >= 0), // Starts with a letter (including Latin alphabets) (a, b) => sortTest(a, b, (x) => /^[a-z\u00C0-\u00F6\u00F8-\u017E]/i.test(x)), // Starts with a number (a, b) => sortTest(a, b, (x) => /^\d/i.test(x)), // Is shorter than sortBelowLen (a, b) => sortTest(a, b, (x) => x.length < sortBelowLen), // Finally, sort by the usual order, but localized (ignore case) (a, b) => a.toLowerCase().localeCompare(b.toLowerCase()), ]; // Calls boolean testFun with a and b, returns the proper value for sort(): // -1 if a only 'a' gives true with testFun, 1 if b, 0 if both const sortTest = (a, b, testFun) => (testFun(b) ? 1 : 0) - (testFun(a) ? 1 : 0); // Runs comparisons in sortTests until a sorting difference is found const multiSort = (a, b) => { for (const comparison of sortTests) { // console.log(a, b, comparison(a, b)); const result = comparison(a, b); if (result !== 0) { return result; } } return 0; } strings.sort(multiSort); console.log(strings); console.log('Vs. default sort:') strings.sort(); console.log(strings)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.