{"_id":"relevancy","_rev":"7-4e75f3778f3999abfeb937acd8709c25","name":"relevancy","description":"Unidirectional string relevancy","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"relevancy","description":"Unidirectional string relevancy","version":"0.1.0","author":{"name":"James Padolsey https://github.com/padolsey"},"bugs":{"url":"http://github.com/padolsey/relevancy.js/issues"},"repository":{"type":"git","url":"git://github.com/padolsey/relevancy.js.git"},"main":"lib/relevancy","licenses":[],"contributors":[{"name":"James Padolsey","url":"http://github.com/padolsey"}],"_npmUser":{"name":"padolsey","email":"npm@padolsey.net"},"_id":"relevancy@0.1.0","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.105","_nodeVersion":"v0.4.4","_defaultsLoaded":true,"dist":{"shasum":"81a6d1e6b4d4b281e27119aacd64324df0ec4b7c","tarball":"https://registry.npmjs.org/relevancy/-/relevancy-0.1.0.tgz","integrity":"sha512-zdxD8m/g7VtH8QpeWwAWE77n76OxZxDgBIegb7/+VADxl3lQ+KvbeG/qJYbIZ9spWnPRiW2N0T2vx/l1WdxmTw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEzsnlL9z372cEZbfTYsFY9WmAIsBiuYuJ7GjfUJZqE/AiAdf8XoUmUlmvaP0u89KcnpZCjPDu2fdNRHtX/Y9Je9aw=="}]},"maintainers":[{"name":"padolsey","email":"npm@padolsey.net"}]},"0.2.0":{"name":"relevancy","description":"Unidirectional string relevancy","version":"0.2.0","author":{"name":"James Padolsey https://github.com/padolsey"},"bugs":{"url":"http://github.com/padolsey/relevancy.js/issues"},"repository":{"type":"git","url":"git://github.com/padolsey/relevancy.js.git"},"main":"lib/relevancy","licenses":[],"contributors":[{"name":"James Padolsey","url":"http://github.com/padolsey"}],"_npmUser":{"name":"padolsey","email":"npm@padolsey.net"},"_id":"relevancy@0.2.0","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.0-beta-7","_nodeVersion":"v0.7.4-pre","_defaultsLoaded":true,"dist":{"shasum":"230600b24b465f26055e23730a1378b6f329cedb","tarball":"https://registry.npmjs.org/relevancy/-/relevancy-0.2.0.tgz","integrity":"sha512-82t+iJxDkkMQvGDmw9uttVedyXqyN2gQKXjHcMzG3HcKXomjYJD0lBLL/7fZ7O+CRmcjPPKPc4Ye8HuyZQWTEw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjpHTxkEnYmQPAnucKqhYnm88j2yvZkCzUUn/KxlbDXQIhAONGqPkx747ft6vKpcPuGZts6aE7L5Cwign3Y5fWHvzo"}]},"readme":"# relevancy Sorter/Weighter\n\n*Using node.js? Install: `npm install relevancy`.*\n\n## Objective\n\nThe original purpose behind relevancy.js was to sort an array of items based on each element's relevancy to a single string. This is exactly what autocompletion widgets/scripts claim to do, but many of them suck for the following reasons:\n\n * They only take into account partial matches at the beginning of the strings. If I type \"nited kingdom\" (missing a \"u\") nothing will show up.\n * They don't actually sort the results dependent on relevancy -- they just show you where the partial matches have been found, in alphabetical order usually. Match length/position is rarely considered.\n\nE.g.\n\n * Go [here](http://jqueryui.com/demos/autocomplete/) and type in the letter \"C\" ... Does the order of the suggestions make any sense? Shouldn't it be ordered like: C, C++, Clojure, ... ?\n * Go [here](http://www.vonloesch.de/node/18) and type \"oris\" (Missing \"B\"). No results.\n * Go [here](http://dhtmlx.com/docs/products/dhtmlxCombo/index.shtml) and type \"Kingdom\" in the top-right field. The result \"united kingdom\" does not show...\n\nThe basic partial-matching implemented by most autocompletion scripts can hamper usability.\n\nHopefully, relevancy.js can rectify this with its not-so-complex weighting algorithm.\n\n## Intro\n\n**[Version: 0.2.0]**\n\nrelevancy.js contains a basic sorting/weighting algorithm that can be used to weight a short string relative to another short string. It can gage the relevancy between two strings, but only in a unidirectional manner (`\"Lon\"` is more *relevant* to `\"London\"` than `\"London\"` is to `\"Lon\"`). This was intentional as its main use-case is autocompletion -- i.e. matching partial typed words against large data lists.\n\n```javascript\nrelevancy.weight('Ame', 'America') > relevancy.weight('Ame', 'Armenia'); // => true\n\n// Explanation:\n// \"Ame\" has a higher relevancy weighting to \"America\" than to \"Armenia\"\n```\n\nThe *subject* of a single weighting or sorting operation is the string that is being compared against the target string or array. For example:\n\n```javascript\nvar subject = 'G';\nvar array = ['Apple', 'Banana', 'Grape', 'Mango'];\n\nrelevancy.sort(array, subject); // => ['Grape', 'Mango', 'Apple', 'Banana']\n```\n\nThe elements have been sorted by their relevancy to the subject \"G\", taking the following weights into account:\n\n * `matchInSubjectLength`: (`0..1`) The proportion of the largest substring match found within the actual subject. So, if the subject is `\"Gu\"`, but we only match `\"G\"` (e.g. in `\"Grape\"`) then proportion would be `0.5`.\n * `matchInSubjectIndex`: (`0..1`) The proximity of the match to the start of the subject. For example, given the subject `\"A grape\"` against the value `\"Grapelicious\"`, `\"grape\"` in `\"A grape\"` matches the beginning of the value, and it is at an index of `2`. The highest possible index of this is `2` (given the match's length: `5`) so `matchInSubjectIndex`, in this example, gets set as zero.\n * `matchInValueLength`: (`0..1`) The proportion of the largest substring match found within the target value. For example, we matched the substring `\"King\"` (length:`4`) against the value `\"United Kingdom\"` (length:`14`), and `4/14 = ~0.29` **This is not used currently.**, although can be set when you pass a configuration object to `relevancy.Sorter`.\n * `matchInValueIndex`: (`0..1`) The proximity of the match to the start of the target value. E.g., a match of `\"dom\"` in `\"Kingdom\"` -- `\"dom\"` is matched at an index of `4`. `4` divided by the total length of `7` substracted from `1` gives us our `matchInValueIndex` of `~0.43`.\n\nNote that the algorithm will account for spaces and anchor the calculations above accordingly. So `\"Banana Milkshake\"` will be weighted higher than `\"bananamilk\"` given the subject `\"milk\"` because it begins a word in the former `\"Banana Milkshake\"` but merely forms a part of another word in the latter, `\"bananamilk\"`.\n\nThe default bound of `\\s+` is used to find where the calculations should be anchored. You can add your own bounds via the configuration option: `bounds`.\n\n## Example Implementation\n\n```javascript\n// In this example, we'll also see how relevancy.js can\n// deal with nested arrays. Default operation is `max`,\n// meaning that it'll get the maximum weight from each sub-array\n// and use that for comparing to other sub-arrays.\n\nvar countries = [\n\t['AF', 'Afghanistan'],\n\t['AL', 'Albania'],\n\t['DZ', 'Algeria'],\n\t['AS', 'American Samoa'],\n\t['AD', 'Andorra'],\n\t['AO', 'Angola'],\n\t// .......\n];\n\nvar countrySorter = relevancy.Sorter(null, countries);\n\ncountrySorter.sortBy('Al').slice(0, 5); // => [[\"AL\", \"Albania\"], [\"DZ\", \"Algeria\"]...]\n```\n\n## Configuration\n\nIf you want more control you should create a `relevancy.Sorter` instance which can accept a configuration object upon instantiation:\n\n```javascript\nvar mySorter = new relevancy.Sorter({\n\n\tbounds: ['\\\\s', '(?=[A-Z])', '-'], // create new bounds (default: ['\\\\s'])\n\n\tcomparator: function(a, b) {\n\t\t// When relevancy.Sorter finds two items with equal weight\n\t\t// it will pass them to this function so you can decide \n\t\t// what to do. I.e. return -1, 1\n\t\t// Only return 0 if you're prepared for the pain caused \n\t\t// by unstable sorting algorithms in e.g. V8\n\t},\n\n\tweights: {\n\t\t// Define your own weights (each of these is described further up)\n\t\t// ** These are the default values:\n\t\t// (yes, one of them is zero)\n\t\tmatchInSubjectLength: 1,\n\t\tmatchInSubjectIndex: .5,\n\t\tmatchInValueLength: 0,\n\t\tmatchInValueIndex: 1\n\t}\n\n});\n\n// Usage:\nmySorter.setArray( arrayToSearch );\nmySorter.sortBy('thingToFind');\n\n// Or:\nmySorter.sort(arrayToSearch, 'thingToFind');\n```\n\n## Changelog\n\n * **0.2**\n \t* `subArrayWeightOperation` option renamed to `subWeightOperation` (because it's used for regular sub-objects as well as arrays)\n \t* Arguments passed to `subWeightOperation` are now simplified and only include the sub-item and a `calc` function which you call to determine the actual weight. The resulting weight should be returned from your custom `subWeightOperation` function.\n \t* `subWeightOperation` option added to `sort` method. See [issue #1](https://github.com/padolsey/relevancy.js/issues/1).\n\n## Todo\n\n * Tidy up\n * Configuration options\n * MORE tests","maintainers":[{"name":"padolsey","email":"npm@padolsey.net"}]}},"readme":null,"maintainers":[{"name":"padolsey","email":"npm@padolsey.net"}],"time":{"modified":"2022-06-26T10:57:47.322Z","created":"2011-11-27T15:34:21.527Z","0.1.0":"2011-11-27T15:34:22.046Z","0.2.0":"2012-03-02T20:50:31.247Z"},"author":{"name":"James Padolsey https://github.com/padolsey"},"repository":{"type":"git","url":"git://github.com/padolsey/relevancy.js.git"}}