How to find the single different character between two strings in JavaScript

Here is one way to find the single different character between two strings in JavaScript.
Space complexity: O(n)
Time complexity: O(n)

singleDifferentCharTry in REPL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Assumptions:
// - All strings are lowercase
// - inputs might be null
// - strings fits in memory
// - strings are in ASCII
// - strings can be in different orders
// - there will be some difference between the two strings
function singleDifferentChar(str1, str2) {
if (typeof str1 !== 'string' || typeof str2 !== 'string') {
throw new Error(`One or both of your inputs is not a string. Please use two strings - str1: ${str1} str2: ${str2} `);
}
const str1CharCount = getCharCountMap(str1);
const str2CharCount = getCharCountMap(str2);
return findDifference(str1CharCount, str2CharCount)
}
// returns a character count map given a string
function getCharCountMap(string) {
return string.split('').reduce((map, char) => {
map[char] = map[char] + 1 || 1;
return map;
}, {})
}
// find the difference between two character count maps
function findDifference(map1, map2) {
const largestMap = Object.keys(map1).length >= Object.keys(map2).length ? map1 : map2;
for (let key in largestMap) {
const isDifferent = map1[key] !== map2[key];
if (isDifferent) return key;
}
}
// A simpler xor implementation
function findDiff(str1, str2) {
if (str1 === null || str2 === null) {
throw new Error('str1 or str2 cannot be null');
}
let result = 0;
for (let i = 0; i < str1.length; i++) {
result ^= str1.charCodeAt(i)
}
for (let i = 0; i < str2.length; i++) {
result ^= str2.charCodeAt(i)
}
return String.fromCharCode(result);
}
// Uncomment to use findDiff
// singleDifferentChar = findDiff
// ==== Tests
function runTests(func) {
const inputOutput = [['abcd', 'abcde', 'e'], ['aaabbcdd', 'abdbacade', 'e']];
for (let i = 0; i < inputOutput.length; i++) {
const input = inputOutput[i].slice(0, inputOutput[i].length-1);
const expected = inputOutput[i][inputOutput[i].length-1];
const result = func(...input);
if (result !== expected) {
return [false, result, expected];
}
}
return [true];
}
let throwsErrorCorrectly = false;
let runsTestSuccessfully = false;
let result, expected;
try {
singleDifferentChar(null, 'input'); // This should throw an error
} catch (e) {
[runsTestSuccessfully, result, expected] = runTests(singleDifferentChar);
throwsErrorCorrectly = true;
} finally {
const message = runsTestSuccessfully && throwsErrorCorrectly ? 'All tests passed' : `Expected: ${expected}. Got ${result}`;
console.log(message);
}
// Test cases
// singleDifferentChar(null, 'input'); // Error!
// singleDifferentChar('abcd', 'abcde') // 'e'
// singleDifferentChar('aaabbcdd', 'abdbacade', 'e') // 'e'