Skip to content

Commit

Permalink
feat: add some fn
Browse files Browse the repository at this point in the history
  • Loading branch information
fupengl committed Jun 6, 2021
1 parent 2d0349d commit 505d9cc
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 38 deletions.
40 changes: 38 additions & 2 deletions __tests__/array.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,45 @@
import { mapPick } from '../src/array';
import { mapPick, arrayToTree } from '../src/array';

describe('array', () => {
test('get', () => {
test('mapPick', () => {
expect(mapPick([{ id: 1, name: 'xx' }], { label: ['name'], value: ['id'] })).toStrictEqual([
{ label: 'xx', value: 1 },
]);
});

test('arrayToTree', () => {
const arr = [
{ id: 1, parentId: 0 },
{ id: 2, parentId: 1 },
{ id: 3, parentId: 2 },
{ id: 4, parentId: 3 },
];
expect(arrayToTree(arr)[0]).toStrictEqual({
children: [
{
id: 1,
parentId: 0,
children: [
{
id: 2,
parentId: 1,
children: [
{
id: 3,
parentId: 2,
children: [
// @ts-ignore
{
id: 4,
parentId: 3,
},
],
},
],
},
],
},
],
});
});
});
Empty file added src/algorithm/index.ts
Empty file.
18 changes: 18 additions & 0 deletions src/array/array-move.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* 移动数组中元素位置
* @param arr
* @param from
* @param to
*/
function arrayMove<T>(arr: T[], from: number, to: number) {
const startIndex = from < 0 ? arr.length + from : from;

if (startIndex >= 0 && startIndex < arr.length) {
const endIndex = to < 0 ? arr.length + to : to;

const [item] = arr.splice(from, 1);
arr.splice(endIndex, 0, item);
}
}

export default arrayMove;
10 changes: 10 additions & 0 deletions src/array/array-random.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* 从数组中随机获取一项
* @param arr {T[]}
* @return {T}
*/
function arrayRandom<T>(arr: T[]): T {
return arr[Math.floor(Math.random() * arr.length)];
}

export default arrayRandom;
88 changes: 57 additions & 31 deletions src/array/array-to-tree.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Dictionary } from '../type';

interface ArrayToTreeArgs<T> {
export interface ArrayToTreeOpts<T, ChildrenKey extends string = 'children'> {
/**
* 主键ID
* @default id
Expand All @@ -15,47 +15,73 @@ interface ArrayToTreeArgs<T> {
* 叶子节点挂载的key
* @default children
*/
childrenKey?: string;
childrenKey?: ChildrenKey;
}

type TreeNode<T extends Dictionary<any>, K extends string = 'children'> = T &
Record<K, TreeNode<T, K>[]>;
type TreeNode<T, K extends string = 'children'> = T & Partial<Record<K, TreeNode<T, K>[]>>;

function arrayToTree<T extends Dictionary<any>, Node = TreeNode<T>>(
arr: T[],
args: ArrayToTreeArgs<T> = {},
): Record<string, Node> {
const { parentPrimaryKey = 'parentId', primaryKey = 'id', childrenKey = 'children' } = args;
/**
* 数组通过关联主键,返回树
* @param arr
* @param opts
* @return tree { { [id]: TreeNode } } 可以根据root节点id获取树
* @example
* const arr = [
* { id: 1, parentId: 0 },
* { id: 2, parentId: 1 },
* { id: 3, parentId: 2 },
* { id: 4, parentId: 3 }
* ]
* const tree = arrayToTree(arr)[0];
* // out
* {
* children: [
* {
* id: 1,
* parentId: 0,
* children: [
* {
* id: 2,
* parentId: 1,
* children: [
* {
* id: 3,
* parentId: 2,
* children: [
* {
* id: 4,
* parentId: 3
* }
* ]
* }
* ]
* }
* ]
* }
* ],
* }
*/
function arrayToTree<
T extends Dictionary<any>,
K extends string,
Opts extends ArrayToTreeOpts<T, K> = ArrayToTreeOpts<T, K>,
Node = TreeNode<T, NonNullable<Opts['childrenKey']>>
>(arr: T[], opts?: Opts): Record<string, Node> {
const { parentPrimaryKey = 'parentId', primaryKey = 'id', childrenKey = 'children' } = opts || {};
const hasOwnProperty = Object.prototype.hasOwnProperty;
return arr.reduce<Record<string, Node>>((branches, item) => {
const parentId = item[parentPrimaryKey];
const itemId = item[primaryKey];
return arr.reduce<Record<string, Node>>((branches, node) => {
const parentId = node[parentPrimaryKey];
const itemId = node[primaryKey];
if (!hasOwnProperty.call(branches, parentId)) {
branches[parentId] = {} as Node;
}
if (!hasOwnProperty.call(branches[parentId], childrenKey)) {
branches[parentId][childrenKey] = [];
branches[parentId][childrenKey as string] = [];
}
branches[parentId][childrenKey].push(item);
branches[itemId] = Object.assign(branches[itemId], item);
branches[parentId][childrenKey as string].push(node);
branches[itemId] = Object.assign(node, branches[itemId]);
return branches;
}, {});
}

export default arrayToTree;

const a = arrayToTree(
[
{ id: 1, pId: 2 },
{ id: 2, pId: 3 },
{ id: 3, pId: 4 },
{ id: 4, pId: 5 },
],
{
primaryKey: 'id',
parentPrimaryKey: 'pId',
childrenKey: 'children1',
},
);

console.log(a[0]);
4 changes: 4 additions & 0 deletions src/array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ export { default as range } from './range';
export { default as chunk } from './chunk';
export { default as mapPick } from './map-pick';
export { default as arrayToMap } from './array-to-map';
export { default as arrayRandom } from './array-random';
export { default as arrayToTree } from './array-to-tree';
export type { ArrayToTreeOpts } from './array-to-tree';
export { default as arrayMove } from './array-move';
1 change: 0 additions & 1 deletion src/ext-object/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export * from './date';
export * from './function';
export * from './things';
export * from './function';
export * from './ext-object';
export * from './object';
export * from './regex_constant';

export type { PropertyName, Dictionary, ClassType } from './type';
10 changes: 10 additions & 0 deletions src/object/flip-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Dictionary } from '../type';

function flipObject<T extends Dictionary<any>>(obj: T): WeakMap<T[keyof T], keyof T> {
return Object.keys(obj).reduce((acc, key) => {
acc[obj[key]] = key;
return acc;
}, new WeakMap());
}

export default flipObject;
3 changes: 3 additions & 0 deletions src/object/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as TimeoutMap } from './timeout-map';
export { default as mapObject } from './map-object';
export { default as flipObject } from './flip-object';
18 changes: 18 additions & 0 deletions src/object/map-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Dictionary } from '../type';

/**
* 遍历obj返回新的对象
* @param obj
* @param predicate
*/
function mapObject<U extends Record<keyof T, any>, T extends Dictionary<any>>(
obj: T,
predicate: (key: keyof T, value: T[keyof T], obj: T) => U[keyof U],
): U {
return Object.keys(obj).reduce<U>((acc, key) => {
acc[key as keyof U] = predicate(key, obj[key], obj);
return acc;
}, {} as U);
}

export default mapObject;
File renamed without changes.
4 changes: 2 additions & 2 deletions src/string/camel-case.ts → src/string/camelcase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* @example
* hello-word -> helloWord
*/
function camelCase(str: string) {
function camelcase(str: string) {
const camelizeRE = /-(\w)/g;
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
}

export default camelCase;
export default camelcase;
9 changes: 9 additions & 0 deletions src/string/capitalize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* 首字母大写
* @param str
*/
function capitalize(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}

export default capitalize;
3 changes: 2 additions & 1 deletion src/string/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as byteLength } from './byte-length';
export { default as byteToReadableSize } from './byte-to-readable-size';
export { default as camelCase } from './camel-case';
export { default as camelcase } from './camelcase';
export { default as capitalize } from './capitalize';
2 changes: 2 additions & 0 deletions src/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface Dictionary<T> {
[index: string]: T;
}

export type Values<T extends object> = T[keyof T];

export interface ClassType<T = any, A = any> {
prototype: T;
new (args?: A): T;
Expand Down

0 comments on commit 505d9cc

Please sign in to comment.