Skip to content

Commit

Permalink
Merge pull request #22 from wxhccc/dev
Browse files Browse the repository at this point in the history
v2.1.0 添加树数据处理函数。优化wp函数ts提示
  • Loading branch information
wxhccc authored Sep 18, 2022
2 parents dca8c16 + e381dd5 commit 7f0aaba
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 21 deletions.
76 changes: 76 additions & 0 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,82 @@ console.log(tree)
*/
```

### `treeAnalyse(tree, options, keys)`

> v2.1.0 add
分析树结构数据,生成一些便于中间处理的数据,可以通过设置keys来控制要处理的数据模块

**parameters:**
- **tree** {TreeNode[] | object} The tree structure need to transform.
- **options** {object} The options.
- **primaryKey** {string} the primary key of node item, default `'id'`
- **labelKey** {string} the primary key of node item, default `'name'`
- **disabledKey** {string} the disabled key of node item, default `'disabled'`
- **childrenKey** {string} the childrenKey key of node item, default `'children'`
- **keys** {('nodes' | 'keyNodeMap' | 'childKeysMaps' | 'disabledKeys')[]} the modules need to handle


**returns**: AnalyseTreeData

Example

```javascript
import { treeAnalyse } from '@wxhccc/es-util'

const tree = [
{
id: 1,
name: 'language',
children: [
{
id: 2,
name: 'english',
children: []
},
{
id: 3,
name: 'chinese',
children: []
}
]
}
]

const result = array2tree(array)
console.log(result)
/* log
{
"nodes": [
{
"id": 1,
"name": "language",
"children": [{…}, {…}]
},
{
"id": 2,
"name": "english",
"children": []
},
{
"id": 3,
"name": "chinese",
"children": []
}
],
"childKeysMaps": {
"1": [2, 3]
},
"keyNodeMap": {
1: {keyVlaue: 1, keyLabel: 'language', parent: undefined, children: [{…}, {…}]},
2: {keyVlaue: 2, keyLabel: 'english', parent: {…}, children: [] },
3: {keyVlaue: 3, keyLabel: 'chinese', parent: {…}, children: [] }
},
"disabledKeys": []
}
*/
```

## validate module

表单验证模块
Expand Down
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,82 @@ console.log(tree)
*/
```

### `treeAnalyse(tree, options, keys)`

> v2.1.0 add
analyse tree data, return an object contain typed handled data

**parameters:**
- **tree** {TreeNode[] | object} The tree structure need to transform.
- **options** {object} The options.
- **primaryKey** {string} the primary key of node item, default `'id'`
- **labelKey** {string} the primary key of node item, default `'name'`
- **disabledKey** {string} the disabled key of node item, default `'disabled'`
- **childrenKey** {string} the childrenKey key of node item, default `'children'`
- **keys** {('nodes' | 'keyNodeMap' | 'childKeysMaps' | 'disabledKeys')[]} the modules need to handle


**returns**: AnalyseTreeData

Example

```javascript
import { treeAnalyse } from '@wxhccc/es-util'

const tree = [
{
id: 1,
name: 'language',
children: [
{
id: 2,
name: 'english',
children: []
},
{
id: 3,
name: 'chinese',
children: []
}
]
}
]

const result = array2tree(array)
console.log(result)
/* log
{
"nodes": [
{
"id": 1,
"name": "language",
"children": [{…}, {…}]
},
{
"id": 2,
"name": "english",
"children": []
},
{
"id": 3,
"name": "chinese",
"children": []
}
],
"childKeysMaps": {
"1": [2, 3]
},
"keyNodeMap": {
1: {keyVlaue: 1, keyLabel: 'language', parent: undefined, children: [{…}, {…}]},
2: {keyVlaue: 2, keyLabel: 'english', parent: {…}, children: [] },
3: {keyVlaue: 3, keyLabel: 'chinese', parent: {…}, children: [] }
},
"disabledKeys": []
}
*/
```

## validate module

### `ChinaIdCardValid(idCard)`
Expand Down
48 changes: 47 additions & 1 deletion __tests__/array-tree-switch.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-env node, jest */
import { array2tree, tree2array } from '../src'
import { array2tree, tree2array, treeAnalyse } from '../src'

describe('#array2tree', function () {
const array = [
Expand Down Expand Up @@ -49,3 +49,49 @@ describe('#tree2array', function () {
})
})
})

describe('#treeAnalyse', function () {
const treeArr = [
{
id: 1,
pid: 0,
name: 'aaaa',
children: [{ id: 2, pid: 1, name: 'aaaa', disabled: true, children: [] }]
},
{ id: 3, pid: 0, name: 'aaaa', children: [] }
]
it('should return an object contain all module data', function () {
const result = treeAnalyse(treeArr)
const { keyNodeMap } = result
expect(result.nodes).toHaveLength(3)
expect(result.childKeysMaps).toEqual({ 1: [2] })
expect(keyNodeMap[2].parent).toBe(keyNodeMap[1])
expect(result.disabledKeys).toEqual([2])
})
it(`should return part of modules when set keys`, function () {
const result = treeAnalyse(treeArr, undefined, ['nodes', 'childKeysMaps'])
expect(result.nodes).toHaveLength(3)
expect(result.childKeysMaps).toEqual({ 1: [2] })
expect(result.keyNodeMap).toEqual({})
expect(result.disabledKeys).toHaveLength(0)
})
const treeArr1 = [
{
key: 1,
pid: 0,
label: 'aaaa',
children: [
{ key: 2, pid: 1, label: 'aaaa', disabled: true, children: [] }
]
}
]
it('you can use options to custom node property', function () {
const result = treeAnalyse(treeArr1, {
primaryKey: 'key',
labelKey: 'label'
})
expect(result.childKeysMaps).toEqual({ 1: [2] })
expect(result.keyNodeMap[1].keyLabel).toBeTruthy()
expect(result.disabledKeys).toEqual([2])
})
})
15 changes: 14 additions & 1 deletion __tests__/promise.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ describe('#awaitWrapper', () => {
})
})

interface Ref<T> {
value: T
}

describe('#wp', () => {
it('should call method twice if lock is function', () => {
const lock = jest.fn()
Expand All @@ -23,7 +27,16 @@ describe('#wp', () => {
return promise
})
it('should switch lockRefHandle value if lock is lockRefHandle', () => {
const loading = { value: false }
const loading: Record<string, boolean> = { value: false }
const promise = wp(Promise.resolve(1), { lock: [loading, 'value'] })
expect(loading.value).toBe(true)
promise.finally(() => {
expect(loading.value).toBe(false)
})
return promise
})
it('test special types such as Ref for lockRefHandle', () => {
const loading: Ref<boolean> = { value: false }
const promise = wp(Promise.resolve(1), { lock: [loading, 'value'] })
expect(loading.value).toBe(true)
promise.finally(() => {
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wxhccc/es-util",
"version": "2.0.2",
"version": "2.1.0",
"description": "A library that contains some useful methods",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand All @@ -23,7 +23,11 @@
"validate",
"mapToObject",
"string-switch",
"mask data"
"mask data",
"event emitter",
"promise",
"requestAnimationFrame",
"page communicate"
],
"author": "wxhccc",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ function getConfig(env) {
__dirname,
'src/value-string-switch/index.ts'
),
'array-tree-switch': path.resolve(__dirname, 'src/array-tree-switch.ts'),
'object-array': path.resolve(__dirname, 'src/object-array.ts'),
promise: path.resolve(__dirname, 'src/promise.ts'),
validate: path.resolve(__dirname, 'src/validate.ts'),
Expand Down
89 changes: 88 additions & 1 deletion src/array-tree-switch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnyFunction } from './types'
import { AnyFunction, StrOrNum } from './types'
import { hasOwnProp, isArr, isFn } from './utils'
export interface Node {
[key: string]: any
Expand All @@ -7,8 +7,13 @@ export interface TreeNode {
[key: string]: any
}
interface Options {
/** 主键key */
primaryKey?: string
/** 文字key */
labelKey?: string
/** 父元素key */
parentKey?: string
/** 子元素集合key */
childrenKey?: string
}
interface TreeOptions extends Options {
Expand Down Expand Up @@ -155,3 +160,85 @@ export function tree2array(tree: Tree, options = {} as NodeOptions) {
getNode(rootTree, null, true)
return nodes
}

export interface TreeKeyNode {
keyVlaue: StrOrNum
keyLabel?: StrOrNum
parent?: TreeKeyNode
children: TreeKeyNode[]
}

export interface AnalyseTreeData<T extends TreeNode = TreeNode> {
nodes: T[]
childKeysMaps: Record<StrOrNum, StrOrNum[]>
keyNodeMap: Record<string, TreeKeyNode>
disabledKeys: StrOrNum[]
}
type AnalyseTreeModule = keyof AnalyseTreeData

interface TreeAnalyseOptions extends Omit<Options, 'parentKey'> {
disabledKey?: string
}
/**
* 分析id唯一的树节点,得到不同结构的数据
* @param treeData 树数据
* @param options 配置项
* @param keys 可指定的数据类型的key,默认返回完整数据
* @returns
*/
export function treeAnalyse<T extends TreeNode = TreeNode>(
treeData: T[],
options?: TreeAnalyseOptions,
keys?: AnalyseTreeModule[]
) {
const result: AnalyseTreeData<T> = {
nodes: [],
childKeysMaps: {},
keyNodeMap: {},
disabledKeys: []
}
const moduleKeys: AnalyseTreeModule[] = Array.isArray(keys)
? keys
: ['nodes', 'keyNodeMap', 'childKeysMaps', 'disabledKeys']
const { primaryKey, labelKey, disabledKey, childrenKey } = {
primaryKey: 'id',
labelKey: 'name',
childrenKey: 'children',
disabledKey: 'disabled',
...options
} as Required<TreeAnalyseOptions>
const [hasNodes, hasCKM, hasKNM, hasDK] = (
Object.keys(result) as AnalyseTreeModule[]
).map((m) => moduleKeys.includes(m))
const readTreeData = (nodes: T[], parent?: TreeKeyNode) => {
nodes.forEach((node) => {
const {
[primaryKey]: key,
[labelKey]: label,
[childrenKey]: children,
[disabledKey]: disabled
} = node
let keyNode: TreeKeyNode | undefined = undefined
if (hasNodes) {
result.nodes.push(node)
}
if (hasKNM && key !== undefined) {
keyNode = { keyVlaue: key, keyLabel: label, parent, children: [] }
parent?.children.push(keyNode)
result.keyNodeMap[key] = keyNode
}
if (hasDK && disabled && key !== undefined) {
result.disabledKeys.push(key)
}

if (Array.isArray(children) && children.length) {
if (hasCKM) {
result.childKeysMaps[key] = children.map((item) => item[primaryKey])
}
readTreeData(children, keyNode)
}
})
}
treeData && readTreeData(treeData)
return result
}
Loading

0 comments on commit 7f0aaba

Please sign in to comment.