Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ardalan Amini committed May 25, 2018
2 parents f2acff8 + 1456076 commit fef2300
Show file tree
Hide file tree
Showing 36 changed files with 1,048 additions and 1,468 deletions.
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ node_js:
- "10"
- "9"
- "8"
- "7"
- "6"

script:
- npm run coveralls || echo "push to coveralls failed"

cache:
directories:
- "node_modules"

notifications:
email:
on_success: never
Expand Down
92 changes: 92 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
* [.max([key])](#Array+max) ⇒ <code>number</code>
* [.median()](#Array+median)[<code>Array</code>](#Array)
* [.min([key])](#Array+min) ⇒ <code>number</code>
* [.nest(id, link)](#Array+nest)[<code>Array.&lt;Object&gt;</code>](#Object)
* [.orderBy([field], [order])](#Array+orderBy)[<code>Array</code>](#Array)
* [.pad(size, [value])](#Array+pad)[<code>Array</code>](#Array)
* [.partition(fn)](#Array+partition)[<code>Array</code>](#Array)
Expand Down Expand Up @@ -529,6 +530,29 @@ Returns the minimum value of a given key
[{a: 1}, {a: 2}, {a: 3}].min('a'); // 1
[{a: {b: 1}}, {a: {b: 2}}, {a: {b: 3}}].min('a.b'); // 1
```
<a name="Array+nest"></a>

### array.nest(id, link) ⇒ [<code>Array.&lt;Object&gt;</code>](#Object)
Given a flat array of objects linked to one another, it will nest them recursively

**Kind**: instance method of [<code>Array</code>](#Array)

| Param | Type |
| --- | --- |
| id | <code>\*</code> |
| link | <code>string</code> |

**Example**
```javascript
const comments = [
{ id: 1, parent_id: null },
{ id: 2, parent_id: 1 },
{ id: 3, parent_id: 1 },
{ id: 4, parent_id: 2 },
{ id: 5, parent_id: 4 }
];
comments.nest(); // [{ id: 1, parent_id: null, children: [...] }]
```
<a name="Array+orderBy"></a>

### array.orderBy([field], [order]) ⇒ [<code>Array</code>](#Array)
Expand Down Expand Up @@ -1235,12 +1259,16 @@ Number.isInstance(2); // true
* [Object](#Object) : <code>object</code>
* _instance_
* [.$camelCaseKeys()](#Object+$camelCaseKeys)[<code>Object</code>](#Object)
* [.$clone(deep)](#Object+$clone)[<code>Object</code>](#Object)
* [.$equals(obj)](#Object+$equals) ⇒ <code>boolean</code>
* [.$get(key)](#Object+$get) ⇒ <code>\*</code>
* [.$invert()](#Object+$invert)[<code>Object</code>](#Object)
* [.$kebabCaseKeys()](#Object+$kebabCaseKeys)[<code>Object</code>](#Object)
* [.$lowerCaseKeys()](#Object+$lowerCaseKeys)[<code>Object</code>](#Object)
* [.$map(fn)](#Object+$map)[<code>Object</code>](#Object)
* [.$mapKeys(fn)](#Object+$mapKeys)[<code>Object</code>](#Object)
* [.$merge(...objects)](#Object+$merge)[<code>Object</code>](#Object)
* [.$omit(arr)](#Object+$omit)[<code>Object</code>](#Object)
* [.$size()](#Object+$size)[<code>Object</code>](#Object)
* [.$snakeCaseKeys()](#Object+$snakeCaseKeys)[<code>Object</code>](#Object)
* _static_
Expand All @@ -1257,6 +1285,52 @@ Creates a new object from the specified object, where all the keys are in camel-
const myObj = { First_name: "Adam", "last-name": "Smith" };
const myObjLower = myObj.$camelCaseKeys(); // {firstName: "Adam", lastName: "Smith"}
```
<a name="Object+$clone"></a>

### object.$clone(deep) ⇒ [<code>Object</code>](#Object)
Creates a (deep) clone of the object

**Kind**: instance method of [<code>Object</code>](#Object)

| Param | Type |
| --- | --- |
| deep | <code>boolean</code> |

**Example**
```javascript
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = a.$clone(true); // a !== b, a.obj !== b.obj
```
<a name="Object+$equals"></a>

### object.$equals(obj) ⇒ <code>boolean</code>
Performs a deep comparison between two values to determine if they are equivalent

**Kind**: instance method of [<code>Object</code>](#Object)

| Param | Type |
| --- | --- |
| obj | <code>\*</code> |

**Example**
```javascript
{ a: [2, { e: 3 }], b: [4], c: 'foo' }.$equals({ a: [2, { e: 3 }], b: [4], c: 'foo' }); // true
```
<a name="Object+$get"></a>

### object.$get(key) ⇒ <code>\*</code>
Retrieve the property indicated by the given selector from the object

**Kind**: instance method of [<code>Object</code>](#Object)

| Param | Type |
| --- | --- |
| key | <code>string</code> |

**Example**
```javascript
{ selector: { to: { val: 'val to select' } } }.$get('selector.to.val'); // 'val to select'
```
<a name="Object+$invert"></a>

### object.$invert() ⇒ [<code>Object</code>](#Object)
Expand Down Expand Up @@ -1349,6 +1423,24 @@ const other = {
};
object.$merge(other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ], c: "foo" }
```
<a name="Object+$omit"></a>

### object.$omit(arr) ⇒ [<code>Object</code>](#Object)
Omits the key-value pairs corresponding to the given keys from an object; or
Creates an object composed of the properties the given function returns falsey for.
The function is invoked with two arguments: (value, key)

**Kind**: instance method of [<code>Object</code>](#Object)

| Param | Type |
| --- | --- |
| arr | <code>Array.&lt;string&gt;</code> \| <code>function</code> |

**Example**
```javascript
{ a: 1, b: '2', c: 3 }.$omit(['b']); // { a: 1, c: 3 }
{ a: 1, b: '2', c: 3 }.$omit((x) => typeof x === 'number'); // { b: '2' }
```
<a name="Object+$size"></a>

### object.$size() ⇒ [<code>Object</code>](#Object)
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# Changelog


## [v0.8.0](https://github.com/ardalanamini/prototyped.js/releases/tag/v0.8.0) *(2018-05-25)*
**Implemented enhancements:**
- `Array.prototype`
- function `nest` added
- `Object.prototype`
- function `merge` improved
- function `clone` added
- function `equals` added
- function `get` added
- function `omit` added


## [v0.7.0](https://github.com/ardalanamini/prototyped.js/releases/tag/v0.7.0) *(2018-05-20)*
**Implemented enhancements:**
- `Object.prototype`
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@

- - -

**More than `100` useful methods collected in one place**

- - -

> if you have a method you think needs to be a part of this package, feel free to contribute
## Installation
Expand Down
1 change: 1 addition & 0 deletions lib/array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import "./limit";
import "./max";
import "./median";
import "./min";
import "./nest";
import "./orderBy";
import "./pad";
import "./partition";
Expand Down
2 changes: 2 additions & 0 deletions lib/array/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as limit from "./limit/method";
import * as max from "./max/method";
import * as median from "./median/method";
import * as min from "./min/method";
import * as nest from "./nest/method";
import * as orderBy from "./orderBy/method";
import * as pad from "./pad/method";
import * as partition from "./partition/method";
Expand Down Expand Up @@ -83,6 +84,7 @@ export {
max,
median,
min,
nest,
orderBy,
pad,
partition,
Expand Down
27 changes: 27 additions & 0 deletions lib/array/nest/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as method from "./method";

declare global {
interface Array<T> {
nest(id?: any, link?: string): object[];
}
}

/**
* Given a flat array of objects linked to one another, it will nest them recursively
* @memberof Array
* @param {*} id
* @param {string} link
* @returns {Object[]}
* @example
* const comments = [
* { id: 1, parent_id: null },
* { id: 2, parent_id: 1 },
* { id: 3, parent_id: 1 },
* { id: 4, parent_id: 2 },
* { id: 5, parent_id: 4 }
* ];
* comments.nest(); // [{ id: 1, parent_id: null, children: [...] }]
*/
Array.prototype.nest = function(id, link): any {
return method(this, id, link);
};
5 changes: 5 additions & 0 deletions lib/array/nest/method.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const method = (arr: any[], id: any = null, link: string = "parent_id"): any[] =>
arr.filter((item) => item[link] === id)
.map((item) => ({ ...item, children: method(arr, item.id) }));

export = method;
44 changes: 44 additions & 0 deletions lib/array/nest/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import "./index";

describe("Array.prototype.nest", () => {
test("Array.prototype.nest", () => {
const comments = [
{ id: 1, parent_id: null },
{ id: 2, parent_id: 1 },
{ id: 3, parent_id: 1 },
{ id: 4, parent_id: 2 },
{ id: 5, parent_id: 4 },
];

expect(comments.nest()).toEqual([
{
id: 1,
parent_id: null,
children: [
{
id: 2,
parent_id: 1,
children: [
{
id: 4,
parent_id: 2,
children: [
{
id: 5,
parent_id: 4,
children: [],
},
],
},
],
},
{
id: 3,
parent_id: 1,
children: [],
},
],
},
]);
});
});
10 changes: 10 additions & 0 deletions lib/array/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const filter = (arr: any[], key: string | undefined, fn: any) => {
if (key) {
const keys = key.split(".");
const reducer = (item: any) => keys.reduce((prev, curr) => prev[curr], item);

return arr.filter((item) => fn(reducer(item)));
}

return arr.filter(fn);
};
10 changes: 2 additions & 8 deletions lib/array/where/method.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as types from "../../types";
import { filter } from "../utils";

const method = (arr: any[], field: string | types.Operator | any, operator?: types.Operator | any, value?: any) => {
if (operator === undefined) {
Expand Down Expand Up @@ -39,14 +40,7 @@ const method = (arr: any[], field: string | types.Operator | any, operator?: typ
throw new TypeError(`Expected 'operator' to be one of ['<', '<=', '=', '<>', '>=', '>'], got ${operator}`);
}

if (field) {
const keys = (field as string).split(".");
const reducer = (item: any) => keys.reduce((prev, curr) => prev[curr], item);

return arr.filter((item) => iterator(reducer(item)));
}

return arr.filter(iterator);
return filter(arr, field, iterator);
};

export = method;
11 changes: 3 additions & 8 deletions lib/array/whereBetween/method.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { filter } from "../utils";

const method = (arr: any[], field: string | any, start: any, end?: any) => {
if (end === undefined) {
end = start as any;
Expand All @@ -7,14 +9,7 @@ const method = (arr: any[], field: string | any, start: any, end?: any) => {

const iterator = (item: any) => item >= start && item <= end;

if (field) {
const keys = (field as string).split(".");
const reducer = (item: any) => keys.reduce((prev, curr) => prev[curr], item);

return arr.filter((item) => iterator(reducer(item)));
}

return arr.filter(iterator);
return filter(arr, field, iterator);
};

export = method;
11 changes: 3 additions & 8 deletions lib/array/whereIn/method.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { filter } from "../utils";

const method = (arr: any[], field: string | any[], value?: any[]) => {
if (value === undefined) {
value = field as any[];
Expand All @@ -6,14 +8,7 @@ const method = (arr: any[], field: string | any[], value?: any[]) => {

const iterator = (item: any) => (value as any[]).indexOf(item) !== -1;

if (field) {
const keys = (field as string).split(".");
const reducer = (item: any) => keys.reduce((prev, curr) => prev[curr], item);

return arr.filter((item) => iterator(reducer(item)));
}

return arr.filter(iterator);
return filter(arr, field as string, iterator);
};

export = method;
10 changes: 2 additions & 8 deletions lib/array/whereLike/method.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as isString from "../../string/isInstance/method";
import { filter } from "../utils";

const method = (arr: any[], field: string | RegExp, value?: string | RegExp) => {
if (value === undefined) {
Expand All @@ -10,14 +11,7 @@ const method = (arr: any[], field: string | RegExp, value?: string | RegExp) =>

const iterator = (item: any) => (value as RegExp).test(item);

if (field) {
const keys = (field as string).split(".");
const reducer = (item: any) => keys.reduce((prev, curr) => prev[curr], item);

return arr.filter((item) => iterator(reducer(item)));
}

return arr.filter(iterator);
return filter(arr, field as string, iterator);
};

export = method;
Loading

0 comments on commit fef2300

Please sign in to comment.