Skip to content
This repository has been archived by the owner on May 1, 2023. It is now read-only.

allow findBestMatch to accept an array of objects #124

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
24 changes: 14 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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;
}
}
53 changes: 52 additions & 1 deletion src/spec/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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();
Expand Down Expand Up @@ -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']);

Expand Down