|
7 | 7 | // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} |
8 | 8 |
|
9 | 9 | function invert(obj) { |
10 | | - const invertedObj = {}; |
11 | | - |
12 | | - for (const [key, value] of Object.entries(obj)) { |
13 | | - invertedObj.key = value; |
| 10 | + // Validate input type |
| 11 | + if (!obj || typeof obj !== "object" || Array.isArray(obj)) { |
| 12 | + throw new Error("Input must be an object"); |
14 | 13 | } |
15 | 14 |
|
16 | | - return invertedObj; |
17 | | -} |
| 15 | + const entries = Object.entries(obj); |
| 16 | + if (entries.length === 0) return {}; |
18 | 17 |
|
19 | | -// a) What is the current return value when invert is called with { a : 1 } |
| 18 | + // take only the values |
| 19 | + const values = entries.map(([_, v]) => v); |
20 | 20 |
|
21 | | -// b) What is the current return value when invert is called with { a: 1, b: 2 } |
| 21 | + // Detect duplicate values |
| 22 | + const hasDuplicate = new Set(values).size !== values.length; |
| 23 | + if (hasDuplicate) { |
| 24 | + throw new Error("Values cannot be duplicated"); |
| 25 | + } |
22 | 26 |
|
23 | | -// c) What is the target return value when invert is called with {a : 1, b: 2} |
| 27 | + const inverted = {}; |
24 | 28 |
|
25 | | -// c) What does Object.entries return? Why is it needed in this program? |
| 29 | + for (const [key, value] of entries) { |
| 30 | + // Validate key and value types |
| 31 | + if ( |
| 32 | + (typeof key !== "string" && typeof key !== "number") || |
| 33 | + (typeof value !== "string" && typeof value !== "number") |
| 34 | + ) { |
| 35 | + throw new Error("Keys and values must be a string or a number"); |
| 36 | + } |
26 | 37 |
|
27 | | -// d) Explain why the current return value is different from the target output |
| 38 | + inverted[value] = key; |
| 39 | + } |
| 40 | + |
| 41 | + return inverted; |
| 42 | +} |
| 43 | +module.exports = invert; |
28 | 44 |
|
29 | | -// e) Fix the implementation of invert (and write tests to prove it's fixed!) |
| 45 | +// a) What is the current return value when invert is called with { a : 1 } |
| 46 | +// the current value is 1 |
| 47 | +// b) What is the current return value when invert is called with { a: 1, b: 2 } |
| 48 | +// the current return value at this call is 2 |
| 49 | +// c) What is the target return value when invert is called with {a : 1, b: 2} |
| 50 | +// the target return value at this call is to supposed to be 'b' |
| 51 | +// d) What does Object.entries return? Why is it needed in this program? |
| 52 | +// Object.entries is used because both key and value are needed to be returned from the loop |
| 53 | +// e) Explain why the current return value is different from the target output |
| 54 | +// it's because the code in the line 13 is only returning single literal property named "key" on every loop iteration, so each assignment overwrites the previous one and the final object ends up with { key: 2 } but the intended inverted output requires using the loop variables as property names (dynamic keys) so each iteration creates a distinct property (for example invertedObj[value] = key), producing separate entries like { 1: 'a', 2: 'b' } instead of repeatedly writing to the same "key" property which the current function is doing |
| 55 | +// f) Fix the implementation of invert (and write tests to prove it's fixed!) |
| 56 | +// Above is the fixed function |
0 commit comments