Skip to content

Commit

Permalink
feat(utils): 新增 traverse
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jun 28, 2020
1 parent 67f870a commit 36d67e9
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/utils/__snapshots__/traverse.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`traverse 综合示例正常 1`] = `
Object {
"x": Object {
"extra": Array [
Object {},
Object {
"ttt": 1,
},
],
"name": "dd",
},
"y": Array [
1,
Object {
"z": true,
},
],
}
`;
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export * from './readFile'
export * from './RichUrl'
export * from './run'
export * from './swap'
export * from './traverse'
export * from './wait'
export * from './Wechat'
// @endindex
60 changes: 60 additions & 0 deletions src/utils/traverse.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { traverse } from './traverse'

describe('traverse', () => {
test('非对象或数组时不触发回调', () => {
for (const item of [1, '3', /ff/, null, () => 1, true, class {}]) {
const cb = jest.fn()
traverse(item, cb)
expect(cb).not.toBeCalled()
}
})

test('是对象或数组时才触发回调', () => {
for (const item of [{ 1: 2 }, [{ x: 1 }, [2]]]) {
const cb = jest.fn()
traverse(item, cb)
expect(cb).toBeCalled()
}
})

test('代码示例正常', () => {
const values: any[] = []
traverse([1, 2, { 3: 4 }], value => {
values.push(value)
})
expect(values).toEqual([1, 2, { 3: 4 }, 4])
})

test('综合示例正常', () => {
const obj = {
x: {
id: '2',
name: 'dd',
extra: [
{
id: 9,
},
{
id: {
tt: 0,
},
ttt: 1,
},
],
},
y: [
1,
{
id: 4,
z: true,
},
],
}
traverse(obj, (value, key, parent) => {
if (key === 'id') {
delete parent[key]
}
})
expect(obj).toMatchSnapshot()
})
})
39 changes: 39 additions & 0 deletions src/utils/traverse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { forOwn, has, isPlainObject } from 'lodash-es'

/**
* 遍历对象和数组。
*
* @param value 要遍历的值
* @param callback 遍历回调
* @returns 返回结果
* @example
* ```typescript
* traverse([1, 2, {3: 4}], value => {
* console.log(value)
* // => 1
* // => 2
* // => {3: 4}
* // => 4
* })
* ```
*/
export function traverse(
value: any,
callback: (value: any, key: string | number, parent: any) => any,
): void {
if (Array.isArray(value)) {
value.forEach((item, index) => {
callback(item, index, value)
if (value[index] !== undefined) {
traverse(item, callback)
}
})
} else if (isPlainObject(value)) {
forOwn(value, (item, key) => {
callback(item, key, value)
if (has(value, key)) {
traverse(item, callback)
}
})
}
}

0 comments on commit 36d67e9

Please sign in to comment.