mozilla

Revision 502511 of Array.prototype.sort()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Array/sort
  • Revision title: Array.prototype.sort()
  • Revision id: 502511
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment cleanup

Revision Content

{{JSRef("Global_Objects", "Array")}}

Summary

The sort() method sorts the elements of an array in place and returns the array. The sort is not necessarily stable. The default sort order is lexicographic (not numeric).

Syntax

arr.sort([compareFunction])

Parameters

compareFunction
Specifies a function that defines the sort order. If omitted, the array is sorted lexicographically (in dictionary order) according to the string conversion of each element.

Description

If compareFunction is not supplied, elements are sorted by converting them to strings and comparing strings in lexicographic ("dictionary" or "telephone book," not numerical) order. For example, "80" comes before "9" in lexicographic order, but in a numeric sort 9 comes before 80.

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
  • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined

So, the compare function has the following form:

function compare(a, b) {
  if (a is less than b by some ordering criterion)
     return -1;
  if (a is greater than b by the ordering criterion)
     return 1;
  // a must be equal to b
  return 0;
}

To compare numbers instead of strings, the compare function can simply subtract b from a:

function compareNumbers(a, b) {
  return a - b;
}

The sort method can be conveniently used with {{jsxref("Operators/function", "function expressions")}} (and closures):

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
    return a - b;
});
print(numbers);

Objects can be sorted given the value of one of their property.

var items = [
  { name: "Edward", value: 21 },
  { name: "Sharpe", value: 37 },
  { name: "And", value: 45 },
  { name: "The", value: -12 },
  { name: "Magnetic" },
  { name: "Zeros", value: 37 }
];
items.sort(function (a, b) {
    if (a.name > b.name)
      return 1;
    if (a.name < b.name)
      return -1;
    // a must be equal to b
    return 0;
});

Examples

Creating, displaying, and sorting an array

The following example creates four arrays and displays the original array, then the sorted arrays. The numeric arrays are sorted without, then with, a compare function.

var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b) {
  return a - b;
}

// again, assumes a print function is defined
console.log("stringArray:", stringArray.join());
console.log("Sorted:", stringArray.sort());

console.log("numberArray:", numberArray.join());
console.log("Sorted without a compare function:", numberArray.sort());
console.log("Sorted with compareNumbers:", numberArray.sort(compareNumbers));

console.log("numericStringArray:", numericStringArray.join());
console.log("Sorted without a compare function:", numericStringArray.sort());
console.log("Sorted with compareNumbers:", numericStringArray.sort(compareNumbers));

console.log("mixedNumericArray:", mixedNumericArray.join());
console.log("Sorted without a compare function:", mixedNumericArray.sort());
console.log("Sorted with compareNumbers:", mixedNumericArray.sort(compareNumbers));

This example produces the following output. As the output shows, when a compare function is used, numbers sort correctly whether they are numbers or numeric strings.

stringArray: Blue,Humpback,Beluga
Sorted: Beluga,Blue,Humpback

numberArray: 40,1,5,200
Sorted without a compare function: 1,200,40,5
Sorted with compareNumbers: 1,5,40,200

numericStringArray: 80,9,700
Sorted without a compare function: 700,80,9
Sorted with compareNumbers: 9,80,700

mixedNumericArray: 80,9,700,40,1,5,200
Sorted without a compare function: 1,200,40,5,700,80,9
Sorted with compareNumbers: 1,5,9,40,80,200,700

Sorting non-ASCII characters

For sorting strings with non-ASCII characters, i.e. strings with accented characters (e, é, è, a, ä, etc.), strings from languages other than English: use {{jsxref("String.localeCompare")}}. This function can compare those characters so they appear in the right order.

var items = ["réservé", "premier", "cliché", "communiqué", "café" ,"adieu"];
items.sort(function (a, b) {
    return a.localeCompare(b);
});
// items is [ 'adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé' ]

Sorting maps

The compareFunction can be invoked multiple times per element within the array. Depending on the compareFunction's nature, this may yield a high overhead. The more work a compareFunction does and the more elements there are to sort, the wiser it may be to consider using a map for sorting. The idea is to walk the array once to extract the actual values used for sorting into a temporary array, sort the temporary array and then walk the temporary array to bring the original array into the right order.

// the array to be sorted
var list = ["Delta", "alpha", "CHARLIE", "bravo"];

// temporary holder of position and sort-value
var map = list.map(function(e, i){
  return {index: i, value: e.toLowerCase()}
})

// sorting the map containing the reduced values
map.sort(function(a, b) {
  return a.value > b.value ? 1 : -1;
});

// container for the resulting order
var result = map.map(function(e){
  return list[e.index]
})

Specifications

Specification Status Comment
ECMAScript 1st Edition Standard Initial definition.
{{SpecName('ES5.1', '#sec-15.4.4.11', 'Array.prototype.sort')}} {{Spec2('ES5.1')}}  
{{SpecName('ES6', '#sec-array.prototype.sort', 'Array.prototype.sort')}} {{Spec2('ES6')}}  

Browser compatibility

{{CompatibilityTable}}
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 1.0 {{CompatGeckoDesktop("1.7")}} 5.5 {{CompatVersionUnknown}} {{CompatVersionUnknown}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}}

See also

  • {{jsxref("Array.prototype.reverse()")}}
  • {{jsxref("String.prototype.localeCompare()")}}

Revision Source

<div>
 {{JSRef("Global_Objects", "Array")}}</div>
<h2>Summary</h2>
<p>The <code><strong>sort()</strong></code> method sorts the elements of an array in place and returns the array. The sort is not necessarily <a href="https://en.wikipedia.org/wiki/Sorting_algorithm#Stability" title="https://en.wikipedia.org/wiki/Sorting_algorithm#Stability">stable</a>. The default sort order is lexicographic (not numeric).</p>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<pre class="syntaxbox">
<code><em>arr</em>.sort([<em>compareFunction</em>])</code></pre>
<h3 id="Parameters" name="Parameters">Parameters</h3>
<dl>
 <dt>
  <code>compareFunction</code></dt>
 <dd>
  Specifies a function that defines the sort order. If omitted, the array is sorted lexicographically (in dictionary order) according to the string conversion of each element.</dd>
</dl>
<h2 id="Description" name="Description">Description</h2>
<p>If <code>compareFunction</code> is not supplied, elements are sorted by converting them to strings and comparing strings in lexicographic ("dictionary" or "telephone book," not numerical) order. For example, "80" comes before "9" in lexicographic order, but in a numeric sort 9 comes before 80.</p>
<p>If <code>compareFunction</code> is supplied, the array elements are sorted according to the return value of the compare function. If <code>a</code> and <code>b</code> are two elements being compared, then:</p>
<ul>
 <li>If <code>compareFunction(a, b)</code> is less than 0, sort <code>a</code> to a lower index than <code>b</code>, i.e. <code>a</code> comes first.</li>
</ul>
<ul>
 <li>If <code>compareFunction(a, b)</code> returns 0, leave <code>a</code> and <code>b</code> unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.</li>
</ul>
<ul>
 <li>If <code>compareFunction(a, b)</code> is greater than 0, sort <code>b</code> to a lower index than <code>a</code>.</li>
</ul>
<ul>
 <li><code>compareFunction(a, b)</code> must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined</li>
</ul>
<p>So, the compare function has the following form:</p>
<pre class="brush: js">
function compare(a, b) {
  if (a is less than b by some ordering criterion)
     return -1;
  if (a is greater than b by the ordering criterion)
     return 1;
  // a must be equal to b
  return 0;
}
</pre>
<p>To compare numbers instead of strings, the compare function can simply subtract <code>b</code> from <code>a</code>:</p>
<pre class="brush: js">
function compareNumbers(a, b) {
  return a - b;
}
</pre>
<p>The <code>sort</code> method can be conveniently used with {{jsxref("Operators/function", "function expressions")}} (and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures" title="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures">closures</a>):</p>
<pre class="brush: js">
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
    return a - b;
});
print(numbers);
</pre>
<p>Objects can be sorted given the value of one of their property.</p>
<pre class="brush: js">
var items = [
  { name: "Edward", value: 21 },
  { name: "Sharpe", value: 37 },
  { name: "And", value: 45 },
  { name: "The", value: -12 },
  { name: "Magnetic" },
  { name: "Zeros", value: 37 }
];
<code class="brush: js">items.sort(function (a, b) {
    if (a.name &gt; b.name)
      return 1;
    if (a.name &lt; b.name)
      return -1;
    // a must be equal to b
    return 0;
});</code></pre>
<h2>Examples</h2>
<h3 id="Example:_Creating.2C_displaying.2C_and_sorting_an_array" name="Example:_Creating.2C_displaying.2C_and_sorting_an_array">Creating, displaying, and sorting an array</h3>
<p>The following example creates four arrays and displays the original array, then the sorted arrays. The numeric arrays are sorted without, then with, a compare function.</p>
<pre class="brush: js">
var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b) {
  return a - b;
}

// again, assumes a print function is defined
console.log("stringArray:", stringArray.join());
console.log("Sorted:", stringArray.sort());

console.log("numberArray:", numberArray.join());
console.log("Sorted without a compare function:", numberArray.sort());
console.log("Sorted with compareNumbers:", numberArray.sort(compareNumbers));

console.log("numericStringArray:", numericStringArray.join());
console.log("Sorted without a compare function:", numericStringArray.sort());
console.log("Sorted with compareNumbers:", numericStringArray.sort(compareNumbers));

console.log("mixedNumericArray:", mixedNumericArray.join());
console.log("Sorted without a compare function:", mixedNumericArray.sort());
console.log("Sorted with compareNumbers:", mixedNumericArray.sort(compareNumbers));
</pre>
<p>This example produces the following output. As the output shows, when a compare function is used, numbers sort correctly whether they are numbers or numeric strings.</p>
<pre>
stringArray: Blue,Humpback,Beluga
Sorted: Beluga,Blue,Humpback

numberArray: 40,1,5,200
Sorted without a compare function: 1,200,40,5
Sorted with compareNumbers: 1,5,40,200

numericStringArray: 80,9,700
Sorted without a compare function: 700,80,9
Sorted with compareNumbers: 9,80,700

mixedNumericArray: 80,9,700,40,1,5,200
Sorted without a compare function: 1,200,40,5,700,80,9
Sorted with compareNumbers: 1,5,9,40,80,200,700
</pre>
<h3 id="Sorting_non-ASCII_characters">Sorting non-ASCII characters</h3>
<p>For sorting strings with non-ASCII characters, i.e. strings with accented characters (e, é, è, a, ä, etc.), strings from languages other than English: use {{jsxref("String.localeCompare")}}. This function can compare those characters so they appear in the right order.</p>
<pre class="brush: js">
var items = ["réservé", "premier", "cliché", "communiqué", "café" ,"adieu"];
<code>items.sort(function (a, b) {
    return a.localeCompare(b);
});
</code>// items is [ 'adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé' ]<code class="brush: js">
</code></pre>
<h3 id="Sorting_maps">Sorting maps</h3>
<p>The <code>compareFunction</code> can be invoked multiple times per element within the array. Depending on the <code>compareFunction</code>'s nature, this may yield a high overhead. The more work a <code>compareFunction</code> does and the more elements there are to sort, the wiser it may be to consider using a map for sorting. The idea is to walk the array once to extract the actual values used for sorting into a temporary array, sort the temporary array and then walk the temporary array to bring the original array into the right order.</p>
<pre class="brush: js">
// the array to be sorted
var list = ["Delta", "alpha", "CHARLIE", "bravo"];

// temporary holder of position and sort-value
var map = list.map(function(e, i){
  return {index: i, value: e.toLowerCase()}
})

// sorting the map containing the reduced values
map.sort(function(a, b) {
&nbsp; return a.value &gt; b.value ? 1 : -1;
});

// container for the resulting order
var result = map.map(function(e){
  return list[e.index]
})
</pre>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>ECMAScript 1st Edition</td>
   <td>Standard</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.4.4.11', 'Array.prototype.sort')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>&nbsp;</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-array.prototype.sort', 'Array.prototype.sort')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>&nbsp;</td>
  </tr>
 </tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<div>
 {{CompatibilityTable}}</div>
<div id="compat-desktop">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Chrome</th>
    <th>Firefox (Gecko)</th>
    <th>Internet Explorer</th>
    <th>Opera</th>
    <th>Safari</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>1.0</td>
    <td>{{CompatGeckoDesktop("1.7")}}</td>
    <td>5.5</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
   </tr>
  </tbody>
 </table>
</div>
<div id="compat-mobile">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Android</th>
    <th>Chrome for Android</th>
    <th>Firefox Mobile (Gecko)</th>
    <th>IE Mobile</th>
    <th>Opera Mobile</th>
    <th>Safari Mobile</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
    <td>{{CompatVersionUnknown}}</td>
   </tr>
  </tbody>
 </table>
</div>
<h2 id="See_also" name="See_also">See also</h2>
<ul>
 <li>{{jsxref("Array.prototype.reverse()")}}</li>
 <li>{{jsxref("String.prototype.localeCompare()")}}</li>
</ul>
Revert to this revision