Skip to content

Commit

Permalink
feat: lodash base findIndex, find (not implementation)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rain120 committed Dec 29, 2019
1 parent 85f32d4 commit 6240f86
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 13 deletions.
13 changes: 11 additions & 2 deletions src/Algorithm/sort/radixSort/__tests__.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-12-01 12:00:19
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:20:52
*/

import { bucketSort } from '.';
Expand All @@ -11,10 +11,19 @@ import { NumberArrayMap } from 'types';
const input: NumberArrayMap = [3, 2, 1, 2, 3, 21, 123, 312, 123, 11];
const input2: NumberArrayMap = [3, 2, 1, 2, 3, 21, 123, 312, 123, 12345, 2222, 111, 11];


test('bucketSort([]) should be []', () => {
expect(bucketSort([])).toEqual([]);
});

test('bucketSort([], 0) should be []', () => {
expect(bucketSort([], 0)).toEqual([]);
});

test('bucketSort([3], 1) should be [3]', () => {
expect(bucketSort([3])).toEqual([3]);
});

test('bucketSort([3], 1) should be [3]', () => {
expect(bucketSort([3], 1)).toEqual([3]);
});
Expand Down
6 changes: 3 additions & 3 deletions src/Algorithm/sort/radixSort/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-12-01 11:39:39
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:15:28
*/

import { NumberArrayMap } from 'types';
import { insertionSort } from '../insertionSort';

export function bucketSort(
arr: NumberArrayMap,
bucketSize: number
bucketSize?: number,
): NumberArrayMap {
if (arr.length === 0) {
return arr;
Expand Down
6 changes: 3 additions & 3 deletions src/Array/arrayMove/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-11-24 20:11:42
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 10:24:02
*/

import { AnyArrayMap } from '../../types';
import { AnyArrayMap } from 'types';

export function arrayMove(array: AnyArrayMap, from: number, to: number): AnyArrayMap {
array = array.slice();
Expand Down
62 changes: 62 additions & 0 deletions src/Array/find/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
> 为了不污染原生的 Array 对象, 实现通过 function 来实现
>
> Eg:
```javascript
// prototype
Array.prototype.find = function(predicate, /* thisArg*/) {}

// ours
function (collection, predicate) {}
```

### 原理

`find` 方法对数组中的每一项元素执行一次 `predicate` 函数, 直至有一个 `predicate` 返回 `true`. 当找到了这样一个元素后, 该方法会立即返回这个元素的值, 否则返回 `undefined`. 注意`predicate` 函数会为数组中的每个索引调用即从 0 到 `length - 1`, 而不仅仅是那些被赋值的索引, 这意味着对于稀疏数组来说, 该方法的效率要低于那些只遍历有值的索引的方法.

- 把传入的 `this` 转换成 `Object`对象, 需要`null`值处理 -> `O`

- 取出 `Object``length` -> `len`

- 判断传入 `predicate` 的是否是 `function`, 抛出异常 `TypeError exception`

- 设置计数器 `k = 0`

- `while k < len`
- `kValue = O[k]`
- `testResult = predicate(thisArg, kValue, k, O)` -> `Boolean`
- `testResult is true, return kValue`
- `Set k to k + 1`
- `Return undefined`

### 参数

- `predicate`

在数组每一项上执行的函数, 接收 3 个参数:

- `element`

当前遍历到的元素

- `index` 可选

当前遍历到的索引

- `array` 可选

数组本身

- `thisArg` 可选

执行回调时用作`this`的对象

### 返回值

返回数组中满足提供的测试函数的第一个元素的值. 否则返回 `undefined`

### 参考

[Find MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

[TC39 Find](https://tc39.es/ecma262/#sec-array.prototype.find)
12 changes: 12 additions & 0 deletions src/Array/find/__test__.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 10:32:42
*/

import { _find } from '.';

// test('_isArray([]) should true', () => {
// expect(_isArray([])).toBe(true);
// });
11 changes: 11 additions & 0 deletions src/Array/find/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 10:31:47
*/

import { isAbsType } from 'utils/type';

export function _find(collection: any, predicate: any): any {
}
6 changes: 3 additions & 3 deletions src/Array/isArray/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-12-02 20:16:48
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:09:21
*/

import { isAbsType } from '../../utils/type';

export function _isArray(target: any): boolean {
return isAbsType(target).toLowerCase() === 'array';
return isAbsType(target).toLowerCase() === 'array';
}
88 changes: 88 additions & 0 deletions src/lodash/.internal/__test__/__tests__.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* @Author: Rainy
* @Date: 2019-12-29 10:44:01
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:25:32
*/

import { baseFindIndex } from '../baseFindIndex';

const input: any = [1, 2, 3, 3, 4, 5, 6, 7];

const inputString: any = ['a', 'b', 'c'];

test(`baseFindIndex(${input}, (item: any, index: number, array: any[]) => {
return item > 3;
}) should be 3`, () => {
expect(
baseFindIndex(
input,
(item: any, index: number, array: any[]) => {
return item > 3;
}
)).toEqual(4);
});

test(`baseFindIndex(${input}, (item: any, index: number, array: any[]) => {
return item > 2;
}) should be 2`, () => {
expect(
baseFindIndex(
input,
(item: any, index: number, array: any[]) => {
return item > 2;
}
)).toEqual(2);
});

test(`baseFindIndex(${input}, (item: any, index: number, array: any[]) => {
return item > 2;
}, 0) should be 2`, () => {
expect(
baseFindIndex(
input,
(item: any, index: number, array: any[]) => {
return item > 2;
},
0
)).toEqual(2);
});

test(`baseFindIndex(${input}, (item: any, index: number, array: any[]) => {
return item > 2;
}, 4, 4) should be 4`, () => {
expect(
baseFindIndex(
input,
(item: any, index: number, array: any[]) => {
return item > 2;
},
4,
4
)).toEqual(4);
});

test(`baseFindIndex(${inputString}, (item: any, index: number, array: any[]) => {
return item === 'a';
}) should be 0`, () => {
expect(
baseFindIndex(
inputString,
(item: any, index: number, array: any[]) => {
return item === 'a';
}
)).toEqual(0);
});


test(`baseFindIndex(${inputString}, (item: any, index: number, array: any[]) => {
return item === 'd';
}) should be 0`, () => {
expect(
baseFindIndex(
inputString,
(item: any, index: number, array: any[]) => {
return item === 'd';
}
)).toEqual(-1);
});
34 changes: 34 additions & 0 deletions src/lodash/.internal/baseFindIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* @Author: Rainy
* @Date: 2019-12-29 10:29:48
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:31:44
*/
import { AnyArrayMap, WithParamsReturnAnyFunction } from '../../types';


/**
* @export
* @param {AnyArrayMap} array
* @param {WithParamsReturnAnyFunction} predicate
* @param {number} fromIndex
* @param {number} fromRight
* @returns {number}
*/
export function baseFindIndex(
array: AnyArrayMap,
predicate: WithParamsReturnAnyFunction,
fromIndex: number = 0,
fromRight?: number
): number {
const { length } = array;
let index = fromIndex + (fromRight ? 1 : -1);

while ((fromRight ? --index : ++index < length)) {
if (!!predicate(array[index], index, array)) {
return index;
}
}

return -1;
}
8 changes: 6 additions & 2 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
/*
* @Author: Rainy
* @Date: 2019-11-14 19:55:36
* @LastEditors: Rainy
* @LastEditTime: 2019-12-01 11:57:26
* @LastEditors : Rainy
* @LastEditTime : 2019-12-29 11:01:00
*/

export class ClassType {}
Expand Down Expand Up @@ -33,6 +33,10 @@ export type ObjectMap<V> = {
// Function
export type NullFunction = () => null;

export type AnyFunction = () => any;

export type WithParamsReturnAnyFunction = (...arg: any) => any;

export type BaseFunction = () => BaseValueType;

export type MixedFunction = () => MixedValueType;
Expand Down

0 comments on commit 6240f86

Please sign in to comment.