diff --git a/package.json b/package.json index 15d7159..35d5162 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,7 @@ "description": "Finds degree of similarity between strings, based on Dice's Coefficient, which is mostly better than Levenshtein distance.", "main": "src/index.js", "scripts": { - "test": "jasmine --config=src/spec/support/jasmine.json", - "build": "rm -rf umd && webpack-cli", - "prepublish": "npm test && npm run build" + "test": "jasmine --config=src/spec/support/jasmine.json" }, "repository": { "type": "git", diff --git a/src/index.js b/src/index.js index 2bbf72d..7238a2b 100644 --- a/src/index.js +++ b/src/index.js @@ -36,16 +36,17 @@ function compareTwoStrings(first, second) { return (2.0 * intersectionSize) / (first.length + second.length - 2); } -function findBestMatch(mainString, targetStrings) { - if (!areArgsValid(mainString, targetStrings)) throw new Error('Bad arguments: First argument should be a string, second should be an array of strings'); +function findBestMatch(mainString, targets, key) { + if (!areArgsValid(mainString, targets, key)) throw new Error('Bad arguments: First argument should be a string, second should be an array of strings, or an array of objects with a key which relates to a string'); const ratings = []; let bestMatchIndex = 0; - for (let i = 0; i < targetStrings.length; i++) { - const currentTargetString = targetStrings[i]; + for (let i = 0; i < targets.length; i++) { + const currentTarget = targets[i] + const currentTargetString = key ? currentTarget[key] : currentTarget; const currentRating = compareTwoStrings(mainString, currentTargetString) - ratings.push({target: currentTargetString, rating: currentRating}) + ratings.push({target: currentTarget, rating: currentRating}) if (currentRating > ratings[bestMatchIndex].rating) { bestMatchIndex = i } @@ -57,10 +58,13 @@ function findBestMatch(mainString, targetStrings) { return { ratings: ratings, bestMatch: bestMatch, bestMatchIndex: bestMatchIndex }; } -function areArgsValid(mainString, targetStrings) { +function areArgsValid(mainString, targets, key) { if (typeof mainString !== 'string') return false; - if (!Array.isArray(targetStrings)) return false; - if (!targetStrings.length) return false; - if (targetStrings.find( function (s) { return typeof s !== 'string'})) return false; + if (!Array.isArray(targets)) return false; + if (!targets.length) return false; + if (targets.find( function (s) { + const string = key ? s[key] : s + return typeof string !== 'string' + })) return false; return true; -} +} \ No newline at end of file diff --git a/src/spec/index.spec.js b/src/spec/index.spec.js index 4153bec..5d9933c 100644 --- a/src/spec/index.spec.js +++ b/src/spec/index.spec.js @@ -36,7 +36,7 @@ describe('compareTwoStrings', function () { describe('findBestMatch', function () { var findBestMatch = stringSimilarity.findBestMatch; - var badArgsErrorMsg = 'Bad arguments: First argument should be a string, second should be an array of strings'; + var badArgsErrorMsg = 'Bad arguments: First argument should be a string, second should be an array of strings, or an array of objects with a key which relates to a string'; it('is a function', function () { expect(typeof findBestMatch).toBe('function'); @@ -47,6 +47,16 @@ describe('findBestMatch', function () { expect(typeof output).toBe('object'); }); + it('accepts a string and an array of objects, and a key which produces a string for all objects, and returns an object', function () { + const inputObject = [ + { name: 'two' }, + { name: 'three' } + ] + var output = findBestMatch('one', inputObject, 'name'); + expect(typeof output).toBe('object'); + }); + + it("throws a 'Bad arguments' error if no arguments passed", function () { expect(function () { findBestMatch(); @@ -79,6 +89,47 @@ describe('findBestMatch', function () { }).toThrowError(badArgsErrorMsg); }); + it("throws a 'Bad arguments' error if second argument is an array of objects, but no key is supplied", function () { + const inputObject = [ + { name: 'two' }, + { name: 'three' } + ] + expect(function () { + findBestMatch('hello', inputObject); + }).toThrowError(badArgsErrorMsg); + }); + + it("throws a 'Bad arguments' error if second argument is an array of objects, and a key is supplied but not all objects have that key", function () { + const inputObject = [ + { name: 'two' }, + { somethingElse: 'three' } + ] + expect(function () { + findBestMatch('hello', inputObject); + }).toThrowError(badArgsErrorMsg); + }); + + it("throws a 'Bad arguments' error if second argument is an array of objects, and a key is supplied but that key does not produce a string for all objects", function () { + const inputObject = [ + { name: 'two' }, + { name: 3 } + ] + expect(function () { + findBestMatch('hello', inputObject); + }).toThrowError(badArgsErrorMsg); + }); + + it("throws a 'Bad arguments' error if second argument is an array and a key is supplied but not all members of the array are objects", function () { + const inputObject = [ + { name: 'two' }, + "three" + ] + expect(function () { + findBestMatch('hello', inputObject); + }).toThrowError(badArgsErrorMsg); + }); + + it('assigns a similarity rating to each string passed in the array', function () { var matches = findBestMatch('healed', ['mailed', 'edward', 'sealed', 'theatre']);