1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: 15.4.4.5-2.js
ECMA Section: Array.prototype.sort(comparefn)
Description:
This test file tests cases in which the compare function is supplied.
In this cases, the sort creates a reverse sort.
The elements of this array are sorted. The sort is not necessarily stable.
If comparefn is provided, it should be a function that accepts two arguments
x and y and returns a negative value if x < y, zero if x = y, or a positive
value if x > y.
1. Call the [[Get]] method of this object with argument "length".
2. Call ToUint32(Result(1)).
1. Perform an implementation-dependent sequence of calls to the
[[Get]] , [[Put]], and [[Delete]] methods of this object and
toSortCompare (described below), where the first argument for each call
to [[Get]], [[Put]] , or [[Delete]] is a nonnegative integer less
than Result(2) and where the arguments for calls to SortCompare are
results of previous calls to the [[Get]] method. After this sequence
is complete, this object must have the following two properties.
(1) There must be some mathematical permutation of the nonnegative
integers less than Result(2), such that for every nonnegative integer
j less than Result(2), if property old[j] existed, then new[(j)] is
exactly the same value as old[j],. but if property old[j] did not exist,
then new[(j)] either does not exist or exists with value undefined.
(2) If comparefn is not supplied or is a consistent comparison
function for the elements of this array, then for all nonnegative
integers j and k, each less than Result(2), if old[j] compares less
than old[k] (see SortCompare below), then (j) < (k). Here we use the
notation old[j] to refer to the hypothetical result of calling the [
[Get]] method of this object with argument j before this step is
executed, and the notation new[j] to refer to the hypothetical result
of calling the [[Get]] method of this object with argument j after this
step has been completely executed. A function is a consistent
comparison function for a set of values if (a) for any two of those
values (possibly the same value) considered as an ordered pair, it
always returns the same value when given that pair of values as its
two arguments, and the result of applying ToNumber to this value is
not NaN; (b) when considered as a relation, where the pair (x, y) is
considered to be in the relation if and only if applying the function
to x and y and then applying ToNumber to the result produces a
negative value, this relation is a partial order; and (c) when
considered as a different relation, where the pair (x, y) is considered
to be in the relation if and only if applying the function to x and y
and then applying ToNumber to the result produces a zero value (of either
sign), this relation is an equivalence relation. In this context, the
phrase "x compares less than y" means applying Result(2) to x and y and
then applying ToNumber to the result produces a negative value.
3.Return this object.
When the SortCompare operator is called with two arguments x and y, the following steps are taken:
1.If x and y are both undefined, return +0.
2.If x is undefined, return 1.
3.If y is undefined, return 1.
4.If the argument comparefn was not provided in the call to sort, go to step 7.
5.Call comparefn with arguments x and y.
6.Return Result(5).
7.Call ToString(x).
8.Call ToString(y).
9.If Result(7) < Result(8), return 1.
10.If Result(7) > Result(8), return 1.
11.Return +0.
Note that, because undefined always compared greater than any other value, undefined and nonexistent
property values always sort to the end of the result. It is implementation-dependent whether or not such
properties will exist or not at the end of the array when the sort is concluded.
Note that the sort function is intentionally generic; it does not require that its this value be an Array object.
Therefore it can be transferred to other kinds of objects for use as a method. Whether the sort function can be
applied successfully to a host object is implementation dependent .
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "15.4.4.5-2";
var VERSION = "ECMA_1";
startTest();
var TITLE = "Array.prototype.sort(comparefn)";
writeHeaderToLog( SECTION + " "+ TITLE);
var S = new Array();
var item = 0;
// array is empty.
S[item++] = "var A = new Array()";
// array contains one item
S[item++] = "var A = new Array( true )";
// length of array is 2
S[item++] = "var A = new Array( true, false, new Boolean(true), new Boolean(false), 'true', 'false' )";
S[item++] = "var A = new Array(); A[3] = 'undefined'; A[6] = null; A[8] = 'null'; A[0] = void 0";
S[item] = "var A = new Array( ";
var limit = 0x0061;
for ( var i = 0x007A; i >= limit; i-- ) {
S[item] += "\'"+ String.fromCharCode(i) +"\'" ;
if ( i > limit ) {
S[item] += ",";
}
}
S[item] += ")";
for ( var i = 0; i < S.length; i++ ) {
CheckItems( S[i] );
}
test();
function CheckItems( S ) {
eval( S );
var E = Sort( A );
new TestCase( SECTION,
S +"; A.sort(Compare); A.length",
E.length,
eval( S + "; A.sort(Compare); A.length") );
for ( var i = 0; i < E.length; i++ ) {
new TestCase(
SECTION,
"A["+i+ "].toString()",
E[i] +"",
A[i] +"");
if ( A[i] == void 0 && typeof A[i] == "undefined" ) {
new TestCase(
SECTION,
"typeof A["+i+ "]",
typeof E[i],
typeof A[i] );
}
}
}
function Object_1( value ) {
this.array = value.split(",");
this.length = this.array.length;
for ( var i = 0; i < this.length; i++ ) {
this[i] = eval(this.array[i]);
}
this.sort = Array.prototype.sort;
this.getClass = Object.prototype.toString;
}
function Sort( a ) {
var r1 = a.length;
for ( i = 0; i < a.length; i++ ) {
for ( j = i+1; j < a.length; j++ ) {
var lo = a[i];
var hi = a[j];
var c = Compare( lo, hi );
if ( c == 1 ) {
a[i] = hi;
a[j] = lo;
}
}
}
return a;
}
function Compare( x, y ) {
if ( x == void 0 && y == void 0 && typeof x == "undefined" && typeof y == "undefined" ) {
return +0;
}
if ( x == void 0 && typeof x == "undefined" ) {
return 1;
}
if ( y == void 0 && typeof y == "undefined" ) {
return -1;
}
x = String(x);
y = String(y);
if ( x < y ) {
return 1;
}
if ( x > y ) {
return -1;
}
return 0;
}
|