1

i am trying to understand array sorting method , the problem i am currently facing is when i am declaring some variables inside compare function its not sorting the same as it is doing without those variables although those variables are not used anywhere

can anyone explain what is actually happening here

also i find out that sort functions behave different in firefox and chrome page_link i am testing this in firefox dev edition

browser_screenshot

let list1 = ["a","b","c","d","e","f","g","h","i"]

list1.sort((a,b)=>{
    let pat = ["d","a"]
    return b - a
})
console.log(list1) // Array(9) [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ]

let list2 = ["a","b","c","d","e","f","g","h","i"]

list2.sort((a,b)=>{
    // let pat = ["d","a"]
    return b - a
})
console.log(list2) // Array(9) [ "i", "h", "g", "f", "e", "d", "c", "b", "a" ]

9
  • @Andy see i have updated my code still same Commented Apr 30, 2022 at 9:04
  • you declare let pat but why? Commented Apr 30, 2022 at 9:06
  • 1
    @MaikLowrey actually i am trying to make a compare function where pat items will be listed first as a practice but while defining it i have noticed that its behaving different Commented Apr 30, 2022 at 9:12
  • ok. i understood. i wrote a answer two point you out that you make a other approach to archive this. Commented Apr 30, 2022 at 9:15
  • @AmirRahman You can consider checking out my answer as well, I've added snippets to explain how you can prepend values after sorting the list. Commented Apr 30, 2022 at 9:18

3 Answers 3

1

If you do "a" - "b" it evaluates to NaN which is incorrect as that's not what you intended and also inconsistent (varies browser to browser).

Either don't pass a callback to sort in which case it does the following:

The sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

Or you can use String.prototype.localeCompare

let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];

console.log([...list].sort());

console.log([...list].sort((a, b) => a.localeCompare(b)));

If you want to prepend some values to the sorted array you'll have to do it separately you can't do it using sort.

let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];

let pat = ["x", "y"];

let sortedList = [...list].sort();

let patAppendedSortedList = [...pat, ...sortedList];

console.log(patAppendedSortedList);

And if you want to sort both the list and pat but you want to keep all pat elements before all list elements then consider the snippet below.

let list = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];

let pat = ["z", "x", "y"];

let patSet = new Set(pat);

let sortedList = [...pat, ...list].sort((a, b) => {
  // If a has higher priority put it before b
  if (patSet.has(a) && !patSet.has(b)) {
    return -1;
  }
  // If b has higher priority put it before a
  if (patSet.has(b) && !patSet.has(a)) {
    return 1;
  }

  // Otherwise both a and b have same priority
  // Sort them according to their value
  return a.localeCompare(b);
});

console.log(sortedList);

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

Comments

1

If you subtract a string from another string, it will attempt to convert the strings to numbers.

All of your strings will convert to NaN.

NaN-NaN is also NaN.

So it doesn't matter which two values from your array you are comparing, your comparison function will always return NaN.

(Note that a comparison function is supposed to return a number that is 0, greater than 0 or less than 0 and be consistent for any given pair of values. The one you are using is just broken for the data you are using).

The order the letters get sorted into therefore depends on the order in which they are compared to each other (because your comparison function is broken).

That order is determined by the sort algorithm that the JS engine uses. This is an implementation detail that the specification doesn't mandate.

One browser might use a quick sort while another might use a bubble sort. Hence you get different results.


Write a comparison function which isn't nonsense to get consistent results.

The default comparison function is find for lexical sorting under most circumstances.

Comments

0

Now i understood your goal. But you cant archive this with your way. You cant make some prepends of values in the JS sort function. You have to make it in two steps. 1.) sort 2.) prepend your pat values to the sorted array.

const list = ["a","b","c","d","e","f","g","h","i"];

const pat = ["d","a"]; 
const sorted = [...pat, ...list.sort()];

console.log(sorted)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.