Skip to content

Commit

Permalink
v0.0.5
Browse files Browse the repository at this point in the history
fixes line endings which caused r.js problems
  • Loading branch information
EyalAr authored and mikaelkaron committed Mar 23, 2015
1 parent bf40695 commit 6d0b3c0
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 4 deletions.
89 changes: 88 additions & 1 deletion README.md
@@ -1 +1,88 @@
[![Version](http://img.shields.io/npm/v/mu-unique.svg)](https://www.npmjs.org/package/mu-unique)[![Version](http://img.shields.io/bower/v/mu-unique.svg)](https://github.com/mu-lib/mu-unique)[![Build Status](https://api.travis-ci.org/mu-lib/mu-unique.svg?branch=master)](https://travis-ci.org/mu-lib/mu-unique)[![Coverage Status](https://img.shields.io/coveralls/mu-lib/mu-unique/master.svg)](https://coveralls.io/r/mu-lib/mu-unique)# mu-uniqueUniqueify an array of elements.**Runtime complexity:** `O(n*log(n))` for sortable arrays, `O(n^2)` fornon-sortable arrays.`unique(arr, sortable, comparator)`0. `arr {Array}` - The source array.0. `sortable {Boolean}` - Optional. Does the array contain sortable elements? **defaults to `false`**.0. `comparator {Function}` - Optional. - If the array is sortable, it defines the order of the elements in the array. It is called with 2 elements from the array and should return `0` if they are equal, a positive number if `a` is bigger and a negative number if `b` is bigger. If not provided, the array will be sorted with a natural order (as defined by the runtime). - If the array is not sortable, it defines the equality between elements in the array. It is called with 2 elements from the array and should return `true` if they are equal, and `false` otherwise. If not provided, the elements will be tested for equality with `===`. **Notes:**0. The function modifies the array and returns its new length.0. The original order of items may not be preserved.0. If the `this` value of the function is defined, it will be used as the array (see examples). Thus it is possible to use this function to extend the Array prototype: `Array.prototype.unique = unique`.## Installation- Node: 0. `npm install mu-unique` 0. `var unique = require('mu-unique');`- AMD (install with bower): 0. `bower install mu-unique` 0. `require(['mu-unique'], function(unique){ /* ... */ });` Run tests with `make test`.Run coverage analysis with `make coverage` (coverage report is saved to `./coverage`).## Examples```Javascriptvar arr = [1, 2, 1, 2, 3], len = unique(arr);console.log(arr, true); // [1, 2, 3]console.log(len); // 3``````Javascriptvar o1 = {}, o2 = function(){}, o3 = "foo", arr = [o1,o1,o2,o3,o2,o3], len = unique(arr);console.log(arr); // [o1, o2, o3]console.log(len); // 3```**With a custom order:**```Javascriptvar arr1 = ['hello', 'hi', 'world'], arr2 = unique(arr1, function(a, b){ // compare only first character return a[0] > b[0] ? 1 : a[0] < b[0] ? -1 : 0; });console.log(arr1); // ['hello', 'hi', 'world']console.log(arr2); // ['hello', 'world']```**By setting the `this` value:**```Javascriptvar arr = [1, 2, 1, 2, 3], len = unique.call(arr);console.log(arr); // [1, 2, 3]console.log(len); // 3```
[![Version](http://img.shields.io/npm/v/mu-unique.svg)](https://www.npmjs.org/package/mu-unique)
[![Version](http://img.shields.io/bower/v/mu-unique.svg)](https://github.com/mu-lib/mu-unique)
[![Build Status](https://api.travis-ci.org/mu-lib/mu-unique.svg?branch=master)](https://travis-ci.org/mu-lib/mu-unique)
[![Coverage Status](https://img.shields.io/coveralls/mu-lib/mu-unique/master.svg)](https://coveralls.io/r/mu-lib/mu-unique)

# mu-unique

Uniqueify an array of elements.

**Runtime complexity:** `O(n*log(n))` for sortable arrays, `O(n^2)` for
non-sortable arrays.

`unique(arr, sortable, comparator)`

0. `arr {Array}` - The source array.
0. `sortable {Boolean}` - Optional. Does the array contain sortable elements?
**defaults to `false`**.
0. `comparator {Function}` - Optional.
- If the array is sortable, it defines the order of the elements in the
array. It is called with 2 elements from the array and should return `0`
if they are equal, a positive number if `a` is bigger and a negative
number if `b` is bigger. If not provided, the array will be sorted with a
natural order (as defined by the runtime).
- If the array is not sortable, it defines the equality between elements
in the array. It is called with 2 elements from the array and should
return `true` if they are equal, and `false` otherwise.
If not provided, the elements will be tested for equality with `===`.

**Notes:**

0. The function modifies the array and returns its new length.
0. The original order of items may not be preserved.
0. If the `this` value of the function is defined, it will be used as the array
(see examples). Thus it is possible to use this function to extend the Array
prototype: `Array.prototype.unique = unique`.

## Installation

- Node:
0. `npm install mu-unique`
0. `var unique = require('mu-unique');`
- AMD (install with bower):
0. `bower install mu-unique`
0. `require(['mu-unique'], function(unique){ /* ... */ });`

Run tests with `make test`.

Run coverage analysis with `make coverage` (coverage report is saved to `./coverage`).

## Examples

```Javascript
var arr = [1, 2, 1, 2, 3],
len = unique(arr);
console.log(arr, true); // [1, 2, 3]
console.log(len); // 3
```

```Javascript
var o1 = {},
o2 = function(){},
o3 = "foo",
arr = [o1,o1,o2,o3,o2,o3],
len = unique(arr);
console.log(arr); // [o1, o2, o3]
console.log(len); // 3
```

**With a custom order:**

```Javascript
var arr1 = ['hello', 'hi', 'world'],
arr2 = unique(arr1, function(a, b){
// compare only first character
return a[0] > b[0] ? 1 : a[0] < b[0] ? -1 : 0;
});
console.log(arr1); // ['hello', 'hi', 'world']
console.log(arr2); // ['hello', 'world']
```

**By setting the `this` value:**

```Javascript
var arr = [1, 2, 1, 2, 3],
len = unique.call(arr);
console.log(arr); // [1, 2, 3]
console.log(len); // 3
```
2 changes: 1 addition & 1 deletion bower.json
@@ -1,6 +1,6 @@
{
"name": "mu-unique",
"version": "0.0.4",
"version": "0.0.5",
"homepage": "https://github.com/mu-lib/mu-unique",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "mu-unique",
"version": "0.0.4",
"version": "0.0.5",
"description": "Uniqueify an array",
"main": "main.js",
"directories": {
Expand Down
127 changes: 126 additions & 1 deletion src/unique.js
@@ -1 +1,126 @@
(function() { 'use strict'; /* istanbul ignore next */ if (typeof define === 'function' && define.amd) { define(['./sorter'], uniqueFactory); } else if (typeof exports === 'object') { module.exports = uniqueFactory( require('./sorter') ); } else { throw Error("no module loader found"); } function uniqueFactory(sorter) { var undefined, DEFAULT_SORTABLE = false; function trivialOrder(a, b) { return a > b ? 1 : a < b ? -1 : 0; } function trivialCompare(a, b) { return a === b; } /** * Assume a sorted array. Remove duplicate elements with one pass. * @param arr A sorted array * @param order * @private */ function _uniqueifySorted(arr, order) { var i = 0, n = 1, len = arr.length; if (len < 2) return; while (i < len) { if (order(arr[i], arr[n - 1]) !== 0) { arr[n] = arr[i]; n++; } i++; } arr.length = n; } /** * Assume an unsorted array. Removes duplicates with two nested loops. * @param arr * @param compare * @private */ function _uniqueifyNotSorted(arr, compare) { var i = 0, j, len = arr.length; while (i < len) { j = i + 1; while (j < len) { if (compare(arr[i], arr[j])) { arr[j--] = arr[--len]; } j++; } i++; } arr.length = len; } /** * Uniqueify an array. * @param arr the array to uniqueify * @param sortable is this array sortable? * @param comparator a function which defines an order for the elements in * the array (if the array is sortabel), or elements equality if it is not. */ return function () { var arr, sortable, comparator, args = Array.prototype.slice.call(arguments, 0); if (args.length === 0) args.push(this); if (args.length === 1) { if (Object.prototype.toString.call(args[0]) !== '[object Array]') args.unshift(this); else args.push(DEFAULT_SORTABLE); } if (args.length === 2) { if (Object.prototype.toString.call(args[0]) !== '[object Array]') { args.unshift(this); } else if (args[1] === true) { args.push(trivialOrder); } else if (args[1] === false) { args.push(trivialCompare); } else { args[2] = args[1]; args[1] = DEFAULT_SORTABLE; } } arr = args[0]; sortable = args[1]; comparator = args[2]; if (Object.prototype.toString.call(arr) !== '[object Array]') throw Error("'arr' must be an array"); if (!(sortable === true || sortable === false)) throw Error("'sortable' must be a boolean"); if (typeof comparator !== 'function') throw Error("'comparator' must be a function"); if (sortable) { sorter(arr, comparator); _uniqueifySorted(arr, comparator); } else { _uniqueifyNotSorted(arr, comparator); } return arr.length; }; }}());
(function() {
'use strict';

/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define(['./sorter'], uniqueFactory);
} else if (typeof exports === 'object') {
module.exports = uniqueFactory(
require('./sorter')
);
} else {
throw Error("no module loader found");
}

function uniqueFactory(sorter) {

var undefined,
DEFAULT_SORTABLE = false;

function trivialOrder(a, b) {
return a > b ? 1 : a < b ? -1 : 0;
}

function trivialCompare(a, b) {
return a === b;
}

/**
* Assume a sorted array. Remove duplicate elements with one pass.
* @param arr A sorted array
* @param order
* @private
*/
function _uniqueifySorted(arr, order) {
var i = 0, n = 1, len = arr.length;
if (len < 2) return;
while (i < len) {
if (order(arr[i], arr[n - 1]) !== 0) {
arr[n] = arr[i];
n++;
}
i++;
}
arr.length = n;
}

/**
* Assume an unsorted array. Removes duplicates with two nested loops.
* @param arr
* @param compare
* @private
*/
function _uniqueifyNotSorted(arr, compare) {
var i = 0, j, len = arr.length;
while (i < len) {
j = i + 1;
while (j < len) {
if (compare(arr[i], arr[j])) {
arr[j--] = arr[--len];
}
j++;
}
i++;
}
arr.length = len;
}

/**
* Uniqueify an array.
* @param arr the array to uniqueify
* @param sortable is this array sortable?
* @param comparator a function which defines an order for the elements in
* the array (if the array is sortabel), or elements equality if it is not.
*/
return function () {

var arr,
sortable,
comparator,
args = Array.prototype.slice.call(arguments, 0);

if (args.length === 0) args.push(this);

if (args.length === 1) {
if (Object.prototype.toString.call(args[0]) !== '[object Array]')
args.unshift(this);
else
args.push(DEFAULT_SORTABLE);
}

if (args.length === 2) {
if (Object.prototype.toString.call(args[0]) !== '[object Array]') {
args.unshift(this);
} else if (args[1] === true) {
args.push(trivialOrder);
} else if (args[1] === false) {
args.push(trivialCompare);
} else {
args[2] = args[1];
args[1] = DEFAULT_SORTABLE;
}
}

arr = args[0];
sortable = args[1];
comparator = args[2];

if (Object.prototype.toString.call(arr) !== '[object Array]')
throw Error("'arr' must be an array");
if (!(sortable === true || sortable === false))
throw Error("'sortable' must be a boolean");
if (typeof comparator !== 'function')
throw Error("'comparator' must be a function");

if (sortable) {
sorter(arr, comparator);
_uniqueifySorted(arr, comparator);
} else {
_uniqueifyNotSorted(arr, comparator);
}

return arr.length;
};
}

}());

0 comments on commit 6d0b3c0

Please sign in to comment.