Skip to content

Commit 86b76df

Browse files
authored
Add a bunch of solutions for LeetCode problem 2724. Sort By (#405)
1 parent 05dfd77 commit 86b76df

File tree

11 files changed

+240
-0
lines changed

11 files changed

+240
-0
lines changed

workspaces/javascript-leetcode-month/problems/2724-sort-by/solution.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,155 @@
1111

1212
## Solutions
1313

14+
### Using `Array.prototype.sort`
15+
16+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378429436/)
17+
18+
```javascript []
19+
/**
20+
* @param {Array} arr
21+
* @param {Function} fn
22+
* @return {Array}
23+
*/
24+
const sortBy = (arr, fn) => arr.sort((a, b) => fn(a) - fn(b));
25+
```
26+
27+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378760710/)
28+
29+
```typescript []
30+
const sortBy = <T>(arr: T[], fn: (value: T) => number): T[] =>
31+
arr.sort((a, b) => fn(a) - fn(b));
32+
```
33+
34+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378760479/)
35+
36+
```typescript []
37+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
38+
[...arr].sort((a, b) => fn(a) - fn(b));
39+
```
40+
41+
### Using `Array.prototype.toSorted`
42+
43+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378760265/)
44+
45+
```javascript []
46+
/**
47+
* @param {Array} arr
48+
* @param {Function} fn
49+
* @return {Array}
50+
*/
51+
const sortBy = (arr, fn) => arr.toSorted((a, b) => fn(a) - fn(b));
52+
```
53+
54+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378759820/)
55+
56+
```typescript []
57+
declare global {
58+
interface Array<T> {
59+
toSorted(this: T[], compareFn: (a: T, b: T) => number): T[];
60+
}
61+
62+
interface ReadonlyArray<T> {
63+
toSorted(this: readonly T[], compareFn: (a: T, b: T) => number): T[];
64+
}
65+
}
66+
67+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
68+
arr.toSorted((a, b) => fn(a) - fn(b));
69+
```
70+
71+
### Minimizing Calls to `fn`
72+
73+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378759536/)
74+
75+
```typescript []
76+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
77+
arr
78+
.map((element) => ({ element, sortKey: fn(element) }))
79+
.sort((a, b) => a.sortKey - b.sortKey)
80+
.map(({ element }) => element);
81+
```
82+
83+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378759168/)
84+
85+
```typescript []
86+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
87+
arr
88+
.map((element): [T, number] => [element, fn(element)])
89+
.sort((a, b) => a[1] - b[1])
90+
.map(([element]) => element);
91+
```
92+
93+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378433879/)
94+
95+
```javascript []
96+
/**
97+
* @param {Array} arr
98+
* @param {Function} fn
99+
* @return {Array}
100+
*/
101+
function sortBy(arr, fn) {
102+
const memoizedFn = _.memoize(fn);
103+
return arr.toSorted((a, b) => memoizedFn(a) - memoizedFn(b));
104+
}
105+
```
106+
107+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378432975/)
108+
109+
```typescript []
110+
function sortBy<T>(arr: readonly T[], fn: (value: T) => number): T[] {
111+
const cache = new Map<T, number>();
112+
const getSortKey = (value: T): number => {
113+
let res = cache.get(value);
114+
if (res == null) {
115+
res = fn(value);
116+
cache.set(value, res);
117+
}
118+
return res;
119+
};
120+
121+
return [...arr].sort((a, b) => getSortKey(a) - getSortKey(b));
122+
}
123+
```
124+
125+
### Implementing Own Sort
126+
127+
[View Submission on LeetCode](https://leetcode.com/problems/sort-by/submissions/1378430770/)
128+
129+
```typescript []
130+
function sortBy<T>(arr: readonly T[], fn: (value: T) => number): T[] {
131+
const n = arr.length;
132+
if (n <= 1) {
133+
return [...arr];
134+
}
135+
136+
const middleIndex = Math.floor(n / 2);
137+
const firstHalf = sortBy(arr.slice(0, middleIndex), fn);
138+
const secondHalf = sortBy(arr.slice(middleIndex), fn);
139+
140+
const res: T[] = [];
141+
142+
let firstHalfCursor = 0;
143+
let secondHalfCursor = 0;
144+
while (
145+
firstHalfCursor < firstHalf.length &&
146+
secondHalfCursor < secondHalf.length
147+
) {
148+
res.push(
149+
fn(firstHalf[firstHalfCursor]) <= fn(secondHalf[secondHalfCursor])
150+
? firstHalf[firstHalfCursor++]
151+
: secondHalf[secondHalfCursor++],
152+
);
153+
}
154+
res.push(
155+
...firstHalf.slice(firstHalfCursor),
156+
...secondHalf.slice(secondHalfCursor),
157+
);
158+
159+
return res;
160+
}
161+
```
162+
14163
## Answers to Bonus Questions
15164

16165
> [!TIP]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function sortBy<T>(arr: readonly T[], fn: (value: T) => number): T[] {
2+
const cache = new Map<T, number>();
3+
const getSortKey = (value: T): number => {
4+
let res = cache.get(value);
5+
if (res == null) {
6+
res = fn(value);
7+
cache.set(value, res);
8+
}
9+
return res;
10+
};
11+
12+
return [...arr].sort((a, b) => getSortKey(a) - getSortKey(b));
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
2+
arr
3+
.map((element) => ({ element, sortKey: fn(element) }))
4+
.sort((a, b) => a.sortKey - b.sortKey)
5+
.map(({ element }) => element);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
2+
arr
3+
.map((element): [T, number] => [element, fn(element)])
4+
.sort((a, b) => a[1] - b[1])
5+
.map(([element]) => element);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @param {Array} arr
3+
* @param {Function} fn
4+
* @return {Array}
5+
*/
6+
function sortBy(arr, fn) {
7+
const memoizedFn = _.memoize(fn);
8+
return arr.toSorted((a, b) => memoizedFn(a) - memoizedFn(b));
9+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const sortBy = <T>(arr: readonly T[], fn: (value: T) => number): T[] =>
2+
[...arr].sort((a, b) => fn(a) - fn(b));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @param {Array} arr
3+
* @param {Function} fn
4+
* @return {Array}
5+
*/
6+
const sortBy = (arr, fn) => arr.sort((a, b) => fn(a) - fn(b));
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const sortBy = <T>(arr: T[], fn: (value: T) => number): T[] =>
2+
arr.sort((a, b) => fn(a) - fn(b));
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function sortBy<T>(arr: readonly T[], fn: (value: T) => number): T[] {
2+
const n = arr.length;
3+
if (n <= 1) {
4+
return [...arr];
5+
}
6+
7+
const middleIndex = Math.floor(n / 2);
8+
const firstHalf = sortBy(arr.slice(0, middleIndex), fn);
9+
const secondHalf = sortBy(arr.slice(middleIndex), fn);
10+
11+
const res: T[] = [];
12+
13+
let firstHalfCursor = 0;
14+
let secondHalfCursor = 0;
15+
while (
16+
firstHalfCursor < firstHalf.length &&
17+
secondHalfCursor < secondHalf.length
18+
) {
19+
res.push(
20+
fn(firstHalf[firstHalfCursor]) <= fn(secondHalf[secondHalfCursor])
21+
? firstHalf[firstHalfCursor++]
22+
: secondHalf[secondHalfCursor++],
23+
);
24+
}
25+
res.push(
26+
...firstHalf.slice(firstHalfCursor),
27+
...secondHalf.slice(secondHalfCursor),
28+
);
29+
30+
return res;
31+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @param {Array} arr
3+
* @param {Function} fn
4+
* @return {Array}
5+
*/
6+
const sortBy = (arr, fn) => arr.toSorted((a, b) => fn(a) - fn(b));

0 commit comments

Comments
 (0)