diff --git a/DIRECTORY.md b/DIRECTORY.md index f2d0bf4fa..2eec03b7b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -299,6 +299,7 @@ * [CountVowels](String/CountVowels.js) * [CreatePermutations](String/CreatePermutations.js) * [DiceCoefficient](String/DiceCoefficient.js) + * [FirstUniqueCharacter](String/FirstUniqueCharacter.js) * [FormatPhoneNumber](String/FormatPhoneNumber.js) * [GenerateGUID](String/GenerateGUID.js) * [HammingDistance](String/HammingDistance.js) diff --git a/String/FirstUniqueCharacter.js b/String/FirstUniqueCharacter.js new file mode 100644 index 000000000..1bacd8307 --- /dev/null +++ b/String/FirstUniqueCharacter.js @@ -0,0 +1,30 @@ +/** + * @function firstUniqChar + * @description Given a string str, find the first non-repeating character in it and return its index. If it does not exist, return -1. + * @param {String} str - The input string + * @return {Number} - The index of first unique character. + * @example firstUniqChar("javascript") => 0 + * @example firstUniqChar("sesquipedalian") => 3 + * @example firstUniqChar("aabb") => -1 + */ + +const firstUniqChar = (str) => { + if (typeof str !== 'string') { + throw new TypeError('Argument should be string') + } + const count = new Map() + + for (const char of str) { + if (!count[char]) { + count[char] = 1 + } else { + count[char]++ + } + } + for (let i = 0; i < str.length; i++) { + if (count[str[i]] === 1) return i + } + return -1 +} + +export { firstUniqChar } diff --git a/String/test/FirstUniqueCharacter.test.js b/String/test/FirstUniqueCharacter.test.js new file mode 100644 index 000000000..b2bc46501 --- /dev/null +++ b/String/test/FirstUniqueCharacter.test.js @@ -0,0 +1,9 @@ +import { firstUniqChar } from '../FirstUniqueCharacter' + +describe('firstUniqChar', () => { + it('locates the index of first unique character in the string', () => { + expect(firstUniqChar('javascript')).toEqual(0) + expect(firstUniqChar('sesquipedalian')).toEqual(3) + expect(firstUniqChar('aabb')).toEqual(-1) + }) +})