| 4 | 4 | // |
| 5 | 5 | |
| 6 | 6 | export class List { |
| 7 | constructor() { | |
| 8 | throw new Error('Remove this line and implement the function'); | |
| 7 | constructor(values = []) { | |
| 8 | this.values = values; | |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | 11 | /** |
| 13 | 13 | * @return {List} |
| 14 | 14 | */ |
| 15 | 15 | append(other) { |
| 16 | throw new Error('Remove this line and implement the function'); | |
| 16 | // Edge Case: Appending an empty list should return the original list | |
| 17 | if (other.length() === 0) { | |
| 18 | return new List(this.values); | |
| 19 | } | |
| 20 | ||
| 21 | const result = []; | |
| 22 | for (let i = 0; i < this.values.length; i++) { | |
| 23 | result.push(this.values[i]); | |
| 24 | } | |
| 25 | for (let i = 0; i < other.values.length; i++) { | |
| 26 | result.push(other.values[i]); | |
| 27 | } | |
| 28 | return new List(result); | |
| 17 | 29 | } |
| 18 | 30 | |
| 19 | 31 | /** |
| 21 | 33 | * @return {List} |
| 22 | 34 | */ |
| 23 | 35 | concat(others) { |
| 24 | throw new Error('Remove this line and implement the function'); | |
| 36 | // Edge Case: Concatenating with an empty list of lists should return the original list | |
| 37 | if (others.length() === 0) { | |
| 38 | return new List(this.values); | |
| 39 | } | |
| 40 | ||
| 41 | let result = new List(this.values); | |
| 42 | for (let i = 0; i < others.values.length; i++) { | |
| 43 | result = result.append(others.values[i]); | |
| 44 | } | |
| 45 | return result; | |
| 25 | 46 | } |
| 26 | 47 | |
| 27 | 48 | /** |
| 29 | 50 | * @return {List} |
| 30 | 51 | */ |
| 31 | 52 | filter(predicate) { |
| 32 | throw new Error('Remove this line and implement the function'); | |
| 53 | // Edge Case: Filtering an empty list should return an empty list | |
| 54 | if (this.length() === 0) { | |
| 55 | return new List([]); | |
| 56 | } | |
| 57 | ||
| 58 | const result = []; | |
| 59 | for (let i = 0; i < this.values.length; i++) { | |
| 60 | if (predicate(this.values[i])) { | |
| 61 | result.push(this.values[i]); | |
| 62 | } | |
| 63 | } | |
| 64 | return new List(result); | |
| 33 | 65 | } |
| 34 | 66 | |
| 35 | 67 | /** |
| 37 | 69 | * @return {List} |
| 38 | 70 | */ |
| 39 | 71 | map(expression) { |
| 40 | throw new Error('Remove this line and implement the function'); | |
| 72 | // Edge Case: Mapping over an empty list should return an empty list | |
| 73 | if (this.length() === 0) { | |
| 74 | return new List([]); | |
| 75 | } | |
| 76 | ||
| 77 | const result = []; | |
| 78 | for (let i = 0; i < this.values.length; i++) { | |
| 79 | result.push(expression(this.values[i])); | |
| 80 | } | |
| 81 | return new List(result); | |
| 41 | 82 | } |
| 42 | 83 | |
| 43 | 84 | /** |
| 44 | 85 | * @return {number} |
| 45 | 86 | */ |
| 46 | 87 | length() { |
| 47 | throw new Error('Remove this line and implement the function'); | |
| 88 | // Edge Case: Length of an empty list should be 0 | |
| 89 | let count = 0; | |
| 90 | for (let i = 0; i < this.values.length; i++) { | |
| 91 | count++; | |
| 92 | } | |
| 93 | return count; | |
| 48 | 94 | } |
| 49 | 95 | |
| 50 | 96 | /** |
| 53 | 99 | * @return {any} |
| 54 | 100 | */ |
| 55 | 101 | foldl(callback, initial) { |
| 56 | throw new Error('Remove this line and implement the function'); | |
| 102 | // Edge Case: Folding an empty list should return the initial value | |
| 103 | if (this.length() === 0) { | |
| 104 | return initial; | |
| 105 | } | |
| 106 | ||
| 107 | let accumulator = initial; | |
| 108 | for (let i = 0; i < this.values.length; i++) { | |
| 109 | accumulator = callback(accumulator, this.values[i]); | |
| 110 | } | |
| 111 | return accumulator; | |
| 57 | 112 | } |
| 58 | 113 | |
| 59 | 114 | /** |
| 62 | 117 | * @return {any} |
| 63 | 118 | */ |
| 64 | 119 | foldr(callback, initial) { |
| 65 | throw new Error('Remove this line and implement the function'); | |
| 120 | // Edge Case: Folding an empty list should return the initial value | |
| 121 | if (this.length() === 0) { | |
| 122 | return initial; | |
| 123 | } | |
| 124 | ||
| 125 | let accumulator = initial; | |
| 126 | for (let i = this.values.length - 1; i >= 0; i--) { | |
| 127 | accumulator = callback(accumulator, this.values[i]); | |
| 128 | } | |
| 129 | return accumulator; | |
| 66 | 130 | } |
| 67 | 131 | |
| 68 | 132 | /** |
| 69 | 133 | * @return {List} |
| 70 | 134 | */ |
| 71 | 135 | reverse() { |
| 72 | throw new Error('Remove this line and implement the function'); | |
| 136 | // Edge Case: Reversing an empty list should return an empty list | |
| 137 | if (this.length() === 0) { | |
| 138 | return new List([]); | |
| 139 | } | |
| 140 | ||
| 141 | const result = []; | |
| 142 | for (let i = this.values.length - 1; i >= 0; i--) { | |
| 143 | result.push(this.values[i]); | |
| 144 | } | |
| 145 | return new List(result); | |
| 73 | 146 | } |
| 74 | 147 | } |
| 148 | ||
| 149 | // Handled Edge Cases: Appending an empty list, concatenating with an empty list of lists, filtering an empty list, mapping over an empty list, length of an empty list, folding an empty list, reversing an empty list |