对象转数组的树形结构

103 阅读1分钟
  • 对象转数组的树形结构,默认子元素使用children作为字段名, 可修改。
  • 默认使用 $parentId $id 方便进行遍历查找 (但不推荐直接遍历,层级太深数据太多的时候会有性能问题,我配合另外加了一个 使用 $id 作为keymap来直接获取/修改值的)
  • 没有添加层级level等字段,根据自己需求添加

对象转数组的树形结构 代码如下:

interface IDataSource {
	$id: string
	$parentId: string
	children?: IDataSource[]
	childrenKeyName?: string
}
export const convertToTreeData = (p: {
	data: any
	parentType?: string
	$parentId?: string
	childrenKeyName?: string
}): IAPITableItemType[] => {
	const {
		data,
		parentType = '',
		$parentId = '',
		childrenKeyName = 'children',
	} = p
	const result = []
	let index = 1

	for (const key in data) {
		if (data.hasOwnProperty(key)) {
			let currentObject = data[key]
			const t: any = typeof currentObject
			let currentType = t

			if (t === 'object' && Array.isArray(currentObject)) {
				currentType = 'array'
				currentObject = [currentObject[0]]
			}
			const id = uuid()
			const item: any = {
				$id: id,
				$parentId: $parentId,
				name: key,
				value: t === 'object' ? '' : currentObject,
				type: currentType,
				parentType,
				required: data?.[key]?.required,
				[childrenKeyName]: undefined as any,
				description: '',
			}

			if (typeof currentObject === 'object' && currentObject !== null) {
				item[childrenKeyName] = convertToTreeData({
					data: currentObject,
					parentType: item.type,
					$parentId: id,
					childrenKeyName: childrenKeyName,
				})
			}

			result.push(item)
			index++
		}
	}

	return result
}

当然,我也提供了 数组转回对象的方法:

export const convertToJSON = (
	treeData: IAPITableItemType[],
	type = 'object'
) => {
	const result: any = {}

	for (const item of treeData) {
		const { name, value, children, type } = item
		if (children && children.length > 0) {
			result[name] = convertToJSON(children, type)
		} else {
			result[name] = value
		}
	}
	if (type === 'array') {
		return Array.from({
			...(result || {}),
			length: Object.keys(result),
		})
	} else {
		return result
	}
}