Skip to content

Commit

Permalink
feat(chunk): 抄了chunk方法及依赖的方法
Browse files Browse the repository at this point in the history
chunk,toFinite,toInteger,toNumber,isObject方法;没有写完整的测试用例,只是保证覆盖率在93%左右
  • Loading branch information
linwens committed Dec 30, 2019
1 parent c3eea59 commit 17c46c2
Show file tree
Hide file tree
Showing 15 changed files with 282 additions and 2 deletions.
6 changes: 5 additions & 1 deletion lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ import divide from './divide';
import mean from './mean';
import meanBy from './meanBy';
import map from './map';
export { Greeter, ArrayEach, DeBounce, eq, add, ceil, divide, mean, meanBy, map };
import chunk from './chunk';
import slice from './slice';
import toNumber from './toNumber';
import isObject from './isObject';
export { Greeter, ArrayEach, DeBounce, eq, add, ceil, divide, mean, meanBy, map, chunk, slice, toNumber, isObject };
8 changes: 8 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,11 @@ var meanBy_1 = __importDefault(require("./meanBy"));
exports.meanBy = meanBy_1.default;
var map_1 = __importDefault(require("./map"));
exports.map = map_1.default;
var chunk_1 = __importDefault(require("./chunk"));
exports.chunk = chunk_1.default;
var slice_1 = __importDefault(require("./slice"));
exports.slice = slice_1.default;
var toNumber_1 = __importDefault(require("./toNumber"));
exports.toNumber = toNumber_1.default;
var isObject_1 = __importDefault(require("./isObject"));
exports.isObject = isObject_1.default;
35 changes: 35 additions & 0 deletions src/__test__/chunk.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { chunk, map } from '../index'
import { falsey, stubArray } from './utils'

describe('chunk', function() {
var array = [0, 1, 2, 3, 4, 5]

it('should return chunked arrays', function() {
var actual = chunk(array, 3)
expect(actual).toEqual([[0, 1, 2], [3, 4, 5]])
})

it('should return the last chunk as remaining elements', function() {
var actual = chunk(array, 4)
expect(actual).toEqual([[0, 1, 2, 3], [4, 5]])
})

it('should treat falsey `size` values, except `undefined`, as `0`', function() {
var expected = map(falsey, function(value) {
return value === undefined ? [[0], [1], [2], [3], [4], [5]] : []
})

var actual = map(falsey, function(size, index) {
return index ? chunk(array, size) : chunk(array)
})
expect(actual).toEqual(expected)
})

// it('should ensure the minimum `size` is `0`', function() {

// });

it('should coerce `size` to an integer', function() {
expect(chunk(array, array.length / 4)).toEqual([[0], [1], [2], [3], [4], [5]])
})
})
18 changes: 18 additions & 0 deletions src/__test__/isObject.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { isObject, map } from '../index'
import { args, slice } from './utils'

describe('isObject', function() {
it('should return `true` for objects', function() {
expect(isObject(args)).toStrictEqual(true)
expect(isObject([1, 2, 3])).toStrictEqual(true)
expect(isObject(Object(false))).toStrictEqual(true)
expect(isObject(new Date())).toStrictEqual(true)
expect(isObject(new Error())).toStrictEqual(true)

expect(isObject(slice)).toStrictEqual(true)
expect(isObject({ a: 1 })).toStrictEqual(true)
expect(isObject(Object(0))).toStrictEqual(true)
expect(isObject(/x/)).toStrictEqual(true)
expect(isObject(Object('a'))).toStrictEqual(true)
})
})
15 changes: 15 additions & 0 deletions src/__test__/slice.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { slice } from '../index'

describe('slice', function() {
var array = [1, 2, 3]

// it('should return [] no array', function() {
// expect(slice(null)).toEqual([]);
// });
it('should work with a negative `start`', function() {
expect(slice(array, -1)).toEqual([3])
})
it('should work with a negative `end`', function() {
expect(slice(array, 0, -1)).toEqual([1, 2])
})
})
18 changes: 18 additions & 0 deletions src/__test__/toNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { toNumber } from '../index'

describe('toNumber', function() {
var array = [1, 2, 3]

// it('should return [] no array', function() {
// expect(slice(null)).toEqual([]);
// });
it('should work with a boolean', function() {
expect(toNumber(false)).toEqual(0)
})
it('should work with a string', function() {
expect(toNumber(' 1 ')).toEqual(1)
expect(toNumber('0b11')).toEqual(3)
expect(toNumber('0o11')).toEqual(9)
expect(toNumber('0x11')).toEqual(17)
})
})
51 changes: 51 additions & 0 deletions src/__test__/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/** Used as a reference to the global object. */
var root = (typeof global == 'object' && global) || this || globalThis

var ArrayBuffer = root.ArrayBuffer,
Map = root.Map,
Promise = root.Promise,
Set = root.Set,
Symbol = root.Symbol,
Uint8Array = root.Uint8Array,
WeakMap = root.WeakMap,
WeakSet = root.WeakSet

var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
map = Map ? new Map() : undefined,
set = Set ? new Set() : undefined,
symbol = Symbol ? Symbol('a') : undefined,
weakMap = WeakMap ? new WeakMap() : undefined,
weakSet = WeakSet ? new WeakSet() : undefined

/** Used for native method references. */
var arrayProto = Array.prototype,
funcProto = Function.prototype,
objectProto = Object.prototype,
numberProto = Number.prototype,
stringProto = String.prototype

/** 将数组转为 arguments */
function toArgs(array: any) {
return function() {
return arguments
}.apply(undefined, array)
}

var falsey = [, null, undefined, false, 0, NaN, '']

var stubArray = function() {
return []
}

var stubTrue = function() {
return true
},
stubFalse = function() {
return false
}

var args = toArgs([1, 2, 3]),
realm = {},
slice = arrayProto.slice

export { falsey, stubArray, args, realm, slice, symbol, stubFalse, toArgs }
21 changes: 21 additions & 0 deletions src/chunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import slice from './slice'
import toInteger from './toInteger'

function chunk(array: any[], size = 1) {
size = Math.max(toInteger(size), 0)
const length = array == null ? 0 : array.length
if (!length || size < 1) {
return []
}
let index = 0
let resIndex = 0
// Math.ceil向上取整,因为会有余数的情况
const result = new Array(Math.ceil(length / size))

while (index < length) {
result[resIndex++] = slice(array, index, (index += size))
}
return result
}

export default chunk
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ import divide from './divide'
import mean from './mean'
import meanBy from './meanBy'
import map from './map'
import chunk from './chunk'
import slice from './slice'
import toNumber from './toNumber'
import isObject from './isObject'

export { Greeter, ArrayEach, DeBounce, eq, add, ceil, divide, mean, meanBy, map }
export { Greeter, ArrayEach, DeBounce, eq, add, ceil, divide, mean, meanBy, map, chunk, slice, toNumber, isObject }
6 changes: 6 additions & 0 deletions src/isObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function isObject(value: any): boolean {
const type = typeof value
return value != null && (type === 'object' || type === 'function')
}

export default isObject
28 changes: 28 additions & 0 deletions src/slice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function slice<T>(array: T[], start = 0, end?: number): T[] {
let length = array == null ? 0 : array.length
if (!length) {
return []
}
start = start == null ? 0 : start
end = end === undefined ? length : end

if (start < 0) {
start = -start > length ? 0 : length + start
}
end = end > length ? length : end
if (end < 0) {
end += length
}
// >>> 无符号移位 >>>0 用于确保前面的表达式有意义,保证其值为非负整数
length = start > end ? 0 : (end - start) >>> 0
start >>>= 0 // => start = start >>> 0

let index = -1
const rslt = new Array(length)
while (++index < length) {
rslt[index] = array[index + start]
}
return rslt
}

export default slice
18 changes: 18 additions & 0 deletions src/toFinite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import toNumber from './toNumber'

const INFINITY = 1 / 0 // => Infinity
const MAX_INTEGER = 1.7976931348623157e308 // Number.MAX_VALUE

function toFinite(value: any) {
if (!value) {
return value === 0 ? value : 0
}
value = toNumber(value)
if (value === INFINITY || value === -INFINITY) {
const sign = value < 0 ? -1 : 1
return sign * MAX_INTEGER
}
return value === value ? value : 0
}

export default toFinite
11 changes: 11 additions & 0 deletions src/toInteger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import toFinite from './toFinite'

function toInteger(value: any) {
const result = toFinite(value)
// 3.2 % 1 => 0.20000000000000018 ; 3 % 1 => 0
const remainder = result % 1 // 获取到result的小数位,如果有的话
// result - remainder 不受浮点数插值影响
return remainder ? result - remainder : result
}

export default toInteger
42 changes: 42 additions & 0 deletions src/toNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import isObject from './isObject'
import isSymbol from './isSymbol'

const NAN = 0 / 0
/** 匹配头尾空白 */
const reTrim = /^\s+|\s+$/g
/** 匹配十六进制 0x前缀 */
const reIsBadHex = /^[-+]0x[0-9a-f]+$/i
/** 匹配二进制 0b前缀 */
const reIsBinary = /^0b[01]+$/i
/** 匹配八进制 0o前缀 */
const reIsOctal = /^0o[0-7]+$/i

const freeParseInt = parseInt

function toNumber(value: any): number {
if (typeof value === 'number') {
return value
}
if (isSymbol(value)) {
return NAN
}
if (isObject(value)) {
// valueOf() =>
const other = typeof value.valueOf === 'function' ? value.valueOf() : value
value = isObject(other) ? `${other}` : other
}
if (typeof value !== 'string') {
return value === 0 ? value : +value
}
value = value.replace(reTrim, '')
const isBinary = reIsBinary.test(value)
return isBinary || reIsOctal.test(value)
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: reIsBadHex.test(value)
? NAN
: +value
}

export default toNumber

// https://segmentfault.com/a/1190000014454306
1 change: 1 addition & 0 deletions tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": ["tslint:recommended", "tslint-config-prettier"],
"rules": {
"no-console": false,
"no-bitwise": false,
"object-literal-sort-keys": false,
"member-access": false,
"ordered-imports": false
Expand Down

0 comments on commit 17c46c2

Please sign in to comment.