Skip to content

Commit 11c227a

Browse files
authored
Array sort (#603)
1 parent e38bb32 commit 11c227a

File tree

3 files changed

+91
-7
lines changed

3 files changed

+91
-7
lines changed

devs/run-tests/24arraymap.ts

+44
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,49 @@ function testArrayAt() {
152152
assert(str.at(-6) === undefined, "arrayAtUndefined")
153153
}
154154

155+
function localeCompareHelper(a: string, b: string) {
156+
if (a < b) return -1
157+
else if (a > b) return 1
158+
else return 0
159+
}
160+
161+
function testArraySort() {
162+
msg("testArraySort")
163+
const arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
164+
arr.sort()
165+
assert(arr.join() === "1,1,2,3,3,4,5,5,5,6,9", "sort1")
166+
167+
const numbers = [9, 3, 7, 1, 5]
168+
numbers.sort((a, b) => a - b)
169+
assert(numbers.join() === "1,3,5,7,9", "sort2")
170+
171+
const words = ["apple", "banana", "cherry", "date"]
172+
words.sort()
173+
assert(words.join() === "apple,banana,cherry,date", "sort3")
174+
175+
const people = [
176+
{ name: "Alice", age: 30 },
177+
{ name: "Bob", age: 25 },
178+
{ name: "Charlie", age: 35 },
179+
]
180+
people.sort((a, b) => a.age - b.age)
181+
assert(people.map(p => p.name).join() === "Bob,Alice,Charlie", "sort4")
182+
183+
const mixed = [5, "apple", 2, "banana", 9, "cherry"]
184+
mixed.sort((a, b) => {
185+
if (typeof a === "string" && typeof b === "string") {
186+
return localeCompareHelper(a, b)
187+
} else if (typeof a === "string") {
188+
return 1 // Strings come after numbers
189+
} else if (typeof b === "string") {
190+
return -1 // Numbers come before strings
191+
} else {
192+
return a - b // Compare numbers
193+
}
194+
})
195+
assert(mixed.join() === "2,5,9,apple,banana,cherry", "sort5")
196+
}
197+
155198
testArraySome()
156199
testArrayEvery()
157200
testArrayFill()
@@ -165,3 +208,4 @@ testArrayFindLastIndex()
165208
testGenerics()
166209
testArrayIncludes()
167210
testArrayAt()
211+
testArraySort()

packages/core/src/array.ts

+24
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,30 @@ Array.prototype.reduce = function (callbackfn: any, initialValue: any) {
169169
return initialValue
170170
}
171171

172+
Array.prototype.sort = function <T>(compareFn?: (a: T, b: T) => number) {
173+
if (!compareFn) {
174+
compareFn = (a: any, b: any) => {
175+
a = a + ""
176+
b = b + ""
177+
if (a < b) return -1
178+
else if (a > b) return 1
179+
else return 0
180+
}
181+
}
182+
183+
for (let i = 1; i < this.length; i++) {
184+
const current = this[i]
185+
let j = i - 1
186+
while (j >= 0 && compareFn(this[j], current) > 0) {
187+
this[j + 1] = this[j]
188+
j--
189+
}
190+
this[j + 1] = current
191+
}
192+
193+
return this
194+
}
195+
172196
Buffer.prototype.set = function (other: Buffer, trgOff?: number) {
173197
if (!trgOff) trgOff = 0
174198
this.blitAt(trgOff, other, 0, other.length)

packages/core/src/corelib.d.ts

+23-7
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,11 @@ interface Array<T> {
215215
[n: number]: T
216216
[Symbol.iterator](): IterableIterator<T>
217217

218-
/**
218+
/**
219219
* Returns the item located at the specified index.
220220
* @param index The zero-based index of the desired code unit. A negative index will count back from the last item.
221221
*/
222-
at(index: number): T | undefined;
222+
at(index: number): T | undefined
223223

224224
/**
225225
* Insert `count` `undefined` elements at `index`.
@@ -286,7 +286,7 @@ interface Array<T> {
286286
* @param end index to stop filling the array at. If end is negative, it is treated as
287287
* length+end.
288288
*/
289-
fill(value: number, start?: number, end?: number): this;
289+
fill(value: number, start?: number, end?: number): this
290290

291291
/**
292292
* Determines whether the specified callback function returns true for any element of an array.
@@ -346,7 +346,9 @@ interface Array<T> {
346346
* order, until it finds one where predicate returns true. If such an element is found, findLast
347347
* immediately returns that element value. Otherwise, findLast returns undefined.
348348
*/
349-
findLast(predicate: (value: T, index: number, array: T[]) => unknown): T | undefined;
349+
findLast(
350+
predicate: (value: T, index: number, array: T[]) => unknown
351+
): T | undefined
350352

351353
/**
352354
* Returns the index of the last element in the array where predicate is true, and -1
@@ -355,7 +357,9 @@ interface Array<T> {
355357
* order, until it finds one where predicate returns true. If such an element is found,
356358
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
357359
*/
358-
findLastIndex(predicate: (value: T, index: number, array: T[]) => unknown): number
360+
findLastIndex(
361+
predicate: (value: T, index: number, array: T[]) => unknown
362+
): number
359363

360364
/**
361365
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
@@ -404,15 +408,27 @@ interface Array<T> {
404408
* @param separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
405409
*/
406410
join(separator?: string): string
411+
412+
/**
413+
* Sorts an array in place using insertion sort -> O(n^2) complexity.
414+
* This method mutates the array and returns a reference to the same array.
415+
* @param compareFn Function used to determine the order of the elements. It is expected to return
416+
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
417+
* value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.
418+
* ```ts
419+
* [11,2,22,1].sort((a, b) => a - b)
420+
* ```
421+
*/
422+
sort(compareFn?: (a: T, b: T) => number): this
407423
}
408424

409425
interface ArrayConstructor {
410426
new (arrayLength?: number): any[]
411427
new <T>(arrayLength: number): T[]
412-
new <T>(...items: T[]): T[];
428+
new <T>(...items: T[]): T[]
413429

414430
(arrayLength?: number): any[]
415-
<T>(...items: T[]): T[];
431+
<T>(...items: T[]): T[]
416432

417433
<T>(arrayLength: number): T[]
418434
isArray(arg: any): arg is any[]

0 commit comments

Comments
 (0)