Skip to content

Commit

Permalink
polyfill added
Browse files Browse the repository at this point in the history
  • Loading branch information
rmdm committed Nov 2, 2017
1 parent 553692b commit 7f39402
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,47 @@ 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
=======

To summarize [usage](#usage) section here is more formal description of **nodups** options:

- **`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.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nodups",
"version": "0.1.3",
"version": "0.2.0",
"description": "No dups, no doubts.",
"main": "dst/nodups.js",
"scripts": {
Expand All @@ -19,7 +19,8 @@
"url": "git+https://github.com/rmdm/nodups.git"
},
"files": [
"dst"
"dst/nodups.js",
"polyfill.js"
],
"keywords": [
"nodups",
Expand Down
1 change: 1 addition & 0 deletions polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dst/nodups').polyfill()
9 changes: 8 additions & 1 deletion src/nodups.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 []
Expand All @@ -37,6 +37,13 @@ export default function (array, options = {}) {
return uniques
}

nodups.polyfill = function () {
Array.prototype.nodups = function (options) {
return nodups(this, options)

This comment has been minimized.

Copy link
@zlumer

zlumer Nov 3, 2017

I guess this can be reduced to
Array.prototype.nodups = nodups
Or am I missing something here?

This comment has been minimized.

Copy link
@zlumer

zlumer Nov 3, 2017

And a check whether nodups already exists on the Array prototype may be useful I think. Just in case some user has a very specific code that overrides this property.

Array.prototype.nodups = [].nodups || nodups

This comment has been minimized.

Copy link
@zlumer

zlumer Nov 3, 2017

Oh I see, the nodups function uses it's first argument as an array. Disregard my first comment.

This comment has been minimized.

Copy link
@rmdm

rmdm Nov 4, 2017

Author Owner

Yes, it may be useful, but I think in general there is no single right decision. Someone may expect for polyfill to overwrite existing properties (especially when he requires it explicitly!). There are examples (like this one) of trying to satisfy both expectations, but it looks ugly, adds noise and neither work for all cases (imagine even more specific code with __forceSmoothScrollPolyfill__ already defined and used somewhere!). Another point is that, unlike, for example, smoothscroll there is no specification for nodups and chances are low for it to appear. So, when one explicitly require the polyfill, he very probably expects [].nodups to be from the library. In the end I think it's a matter of choice and I would probably like to keep things as they are)

}
return nodups
}

function getUniques (array, options) {

const uniques = []
Expand Down
105 changes: 105 additions & 0 deletions test/nodups_polyfill.spec.js
Original file line number Diff line number Diff line change
@@ -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' ])
})
})
})

0 comments on commit 7f39402

Please sign in to comment.