From 7f394022e192d69477c05b95da0c3638cf209f80 Mon Sep 17 00:00:00 2001 From: rmdm Date: Thu, 2 Nov 2017 22:13:54 +0300 Subject: [PATCH] polyfill added --- CHANGELOG.md | 5 ++ README.md | 35 +++++++++++- package.json | 5 +- polyfill.js | 1 + src/nodups.js | 9 ++- test/nodups_polyfill.spec.js | 105 +++++++++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 polyfill.js create mode 100644 test/nodups_polyfill.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7d60348 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +## [0.2.0](https://github.com/rmdm/nodups/compare/v0.1.3...v0.2.0) - 2017-11-02 +- `polyfill()` added + +## 0.1.3 - 2017-11-01 +Initial release. diff --git a/README.md b/README.md index 206da18..606a260 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,39 @@ Installation npm i nodups ``` +Polyfill +======== + +If you would like **nodups** method to be available on array instances like that: + +```javascript +[ 1, 1, 1 ].nodups() // result is [ 1 ] +``` + +than you can `polyfill` it: + +```javascript +require('nodups').polyfill() +// or +require('nodups/polyfill') +// or +import nodups from 'nodups/polyfill' +``` + +In particular, it is handy in case of method chaining: + +```javascript +array + .nodups() + .map(x => x.category) + .nodups() + .filter(x => x.startsWith('_')) + .map(x => getType(x)) + .nodups() +``` + +_Credits to **@zlumer** for his proposal on the polyfill and example._ + Options ======= @@ -174,7 +207,7 @@ To summarize [usage](#usage) section here is more formal description of **nodups - **`inplace`** (Boolean) - drop duplicates from original array. - **`compare`** (Function(a, b)|'==='|'==') - custom comparison function of any two array elements or string shorthand. -- **`strict`** (Boolean) - compare objects' primitive properties with sligtly changed `==` operation (the only difference is that `NaN` values are treated as equal). +- **`strict`** (Boolean) - `true` by default. Compare objects' primitive properties with sligtly changed `==` operation (the only difference is that `NaN` values are treated as equal). - **`sorted`** (Boolean) - tells `nodups` that array is sorted and performance optimization can be applied. - **`by`** (String|Array) - compare objects only by own enumerable properties specified by the paths. - **`skip`** (String|Array) - compare object only by own enumerable properties execept ones specified by the paths. diff --git a/package.json b/package.json index 73ae63b..ff0ed05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nodups", - "version": "0.1.3", + "version": "0.2.0", "description": "No dups, no doubts.", "main": "dst/nodups.js", "scripts": { @@ -19,7 +19,8 @@ "url": "git+https://github.com/rmdm/nodups.git" }, "files": [ - "dst" + "dst/nodups.js", + "polyfill.js" ], "keywords": [ "nodups", diff --git a/polyfill.js b/polyfill.js new file mode 100644 index 0000000..cfb65ef --- /dev/null +++ b/polyfill.js @@ -0,0 +1 @@ +module.exports = require('./dst/nodups').polyfill() diff --git a/src/nodups.js b/src/nodups.js index 7244e0b..6588b25 100644 --- a/src/nodups.js +++ b/src/nodups.js @@ -13,7 +13,7 @@ const isEqualWith = require('lodash.isequalwith') * @param {Function} [options.onUnique] */ -export default function (array, options = {}) { +export default function nodups (array, options = {}) { if (!Array.isArray(array)) { return [] @@ -37,6 +37,13 @@ export default function (array, options = {}) { return uniques } +nodups.polyfill = function () { + Array.prototype.nodups = function (options) { + return nodups(this, options) + } + return nodups +} + function getUniques (array, options) { const uniques = [] diff --git a/test/nodups_polyfill.spec.js b/test/nodups_polyfill.spec.js new file mode 100644 index 0000000..35cac55 --- /dev/null +++ b/test/nodups_polyfill.spec.js @@ -0,0 +1,105 @@ +'use strict' + +import assert from 'assert-match' +import nodups from '../src/nodups' + +describe('nodups polyfill', function () { + + it('is not available until activated', function () { + assert.throws(function () { + [ 1, 1, 1 ].nodups() + }) + }) + + context('when activated', function () { + + before(function () { + nodups.polyfill() + }) + + it('returns nodups module itself', function () { + const polyfilled = nodups.polyfill() + assert.equal(polyfilled, nodups) + }) + + it('makes available nodups convenient method on Array.prototype', function () { + assert.deepEqual([ 1, 1, 1 ].nodups(), [ 1 ]) + }) + + it('added method accepts and applies options', function () { + + const result = [ 15, 5, 14, 33, 73 ].nodups({ + compare: (a,b) => a % 10 === b % 10 + }) + + assert.deepEqual(result, [ 15, 14, 33 ]) + }) + + it('allows for method chaining', function () { + + const array = [ + { + title: 'ball', + category: 'physical activity toys', + }, + { + title: 'frisbee', + category: 'physical activity toys', + }, + { + title: 'ball', + category: 'physical activity toys', + }, + { + title: 'quicksort', + category: 'algorithms', + }, + { + title: 'hard coding', + category: 'anti-patterns', + }, + { + title: 'espresso', + category: 'coffee', + }, + { + title: 'espresso', + category: 'coffee', + }, + { + title: 'magic number', + category: 'anti-patterns', + }, + { + title: 'espresso', + category: 'coffee', + }, + { + title: 'hard coding', + category: 'anti-patterns', + }, + ] + + const categoryTypes = { + 'physical activity toys': 'toys', + 'algorithms': 'programming', + 'anti-patterns': 'programming', + 'coffee': 'drinks', + } + + function getType (category) { + return categoryTypes[category] + } + + const result = array + .nodups() + .map(x => x.category) + .nodups() + .filter(x => x[0] === 'a') + .map(getType) + .nodups() + + assert(result, [ 'programming' ]) + }) + }) +})