Skip to content

Commit 60424b3

Browse files
committed
Write-up for LeetCode problem 2626. Array Reduce Transformation
1 parent 9967f2a commit 60424b3

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22

33
[View Problem on LeetCode](https://leetcode.com/problems/array-reduce-transformation/)
44

5+
This is yet another problem asking us to re-implement some built-in JavaScript function. Here, it's actually slightly simpler than the built-in -- whereas [`Array.prototype.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) also passes an index to the reducing function, in this problem we don't care about the index, only the value.
6+
7+
We can get a quick accept if we ignore the problem statement's request and use the built-in`.reduce`.
8+
9+
For a more serious solution, we can go with any kind of loop over the array values, updating a result during the loop.
10+
511
Once you've worked on the problem, check out [the full write-up and solution](solution.md)!

workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solution.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,22 @@
77
88
## Summary
99

10+
The solution needs to process all the array elements and pass them through a reducing function. Unlike the [`Array.prototype.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) built-in we're replicating, we don't have to pass in an index to the reducer function, but order still matters, since the reducer could be something like `(accumulator, element) => 2 * accumulator + element`.
11+
12+
Any approach that processes elements in the appropriate order will work well. I'd recommend an iterative solution using a simple loop, though it's a good idea to also become comfortable with recursive implementations.
13+
14+
We can also get accepted by simply using the built-in `.reduce`, since LeetCode doesn't enforce that we don't. Or, we could use [`.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) instead and claim that it's technically not `.reduce`.
15+
1016
## Background
1117

1218
## Solutions
1319

20+
It's solution time!
21+
1422
### Using `Array.prototype.reduce`
1523

24+
Let's kick off using the built-ins, for some quick gratification. In pure JavaScript it's very concise:
25+
1626
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378766665/)
1727

1828
```javascript []
@@ -25,6 +35,8 @@
2535
const reduce = (arr, fn, init) => arr.reduce(fn, init);
2636
```
2737

38+
In TypeScript, let's modify LeetCode's solution template and generalize our function using generics. We'll use one type parameter for the type of the array elements and one for the type of the result, as described in more detail in [another write-up](../2635-apply-transform-over-each-element-in-array/solution.md).
39+
2840
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378765352/)
2941

3042
```typescript []
@@ -35,6 +47,8 @@ const reduce = <TElement, TResult>(
3547
): TResult => arr.reduce(fn, init);
3648
```
3749

50+
We can also get weird. If you're new to JavaScript, please ignore this next solution, it's not meant to be easy to interpret.
51+
3852
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378767802/)
3953

4054
```javascript []
@@ -47,8 +61,14 @@ const reduce = <TElement, TResult>(
4761
const reduce = Function.prototype.call.bind(Array.prototype.reduce);
4862
```
4963

64+
Understanding why the above works was a bonus question in [another write-up](../2635-apply-transform-over-each-element-in-array/solution.md). Read about it there if you're curious, but otherwise don't worry about this code too much.
65+
5066
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378777231/)
5167

68+
### Using `Array.prototype.reduceRight`
69+
70+
For a clearer conscience, we can also go with `.reduceRight`, but we'll have to reverse the array to make sure elements are processed in the appropriate order. The built-in `.reverse` mutates the array it's invoked on, so if we want to avoid mutating the input, we'll have to copy it, using [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) for example.
71+
5272
```typescript []
5373
const reduce = <TElement, TResult>(
5474
arr: readonly TElement[],
@@ -57,6 +77,8 @@ const reduce = <TElement, TResult>(
5777
): TResult => [...arr].reverse().reduceRight(fn, init);
5878
```
5979

80+
We can also use the more recently-added [`.toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) to get a reversed copy of the input. The function is available in LeetCode's environment, but TypeScript doesn't know that it is, so we'll have to help it out by adding some functions to the core interfaces for `Array` and `ReadonlyArray`.
81+
6082
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378778477/)
6183

6284
```typescript []
@@ -79,6 +101,8 @@ const reduce = <TElement, TResult>(
79101

80102
### Iterative
81103

104+
The iterative solutions are the ones I recommend for this problem, because I think they read quite nicely. For example, a simple `for...of` loop works great, since we don't care about indexes:
105+
82106
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378776182/)
83107

84108
```typescript []
@@ -97,6 +121,8 @@ function reduce<TElement, TResult>(
97121
}
98122
```
99123

124+
Alternatively, try a `.forEach`:
125+
100126
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378776438/)
101127

102128
```typescript []
@@ -115,6 +141,8 @@ function reduce<TElement, TResult>(
115141
}
116142
```
117143

144+
If we don't mind mutating the input array, we can also remove elements from it, one-by-one, and destructively reduce to a result:
145+
118146
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378781727/)
119147

120148
```typescript []
@@ -134,6 +162,9 @@ function reduce<TElement, TResult>(
134162
}
135163
```
136164

165+
> [!NOTE]
166+
> **Why use `.reverse` and `.pop` instead of `.shift` in the destructive implementation?** The answer is at the bottom of this doc.
167+
137168
### Recursive
138169

139170
[View Submission on LeetCode](https://leetcode.com/problems/array-reduce-transformation/submissions/1378782688/)

workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[View Problem on LeetCode](https://leetcode.com/problems/filter-elements-from-array/)
44

5-
This is one of many problems that essentially ask us to implement some built-in JavaScript function. Here, we're asked to implement filtering without using [`.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), so of course the first thing we should do is get accepted using `.filter`!
5+
This is one of several problems that essentially ask us to implement some built-in JavaScript function. Here, we're asked to implement filtering without using [`.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), so of course the first thing we should do is get accepted using `.filter`!
66

77
For a more serious solution, a loop that builds the result works just fine.
88

workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ We can also get weird. If you're new to JavaScript, please ignore this next solu
5555
const filter = Function.prototype.call.bind(Array.prototype.filter);
5656
```
5757

58-
Understanding why the above works was a bonus question in [an earlier write-up](../2635-apply-transform-over-each-element-in-array/solution.md). Read about it there if you're curious, but otherwise don't worry about this code too much.
58+
Understanding why the above works was a bonus question in [another write-up](../2635-apply-transform-over-each-element-in-array/solution.md). Read about it there if you're curious, but otherwise don't worry about this code too much.
5959

6060
### Iterate and Build
6161

0 commit comments

Comments
 (0)