npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@csir/tools

v1.0.8

Published

树形结构工具:扁平转树形、清理参数、查找子集ID

Readme

CSIR 数据结构处理工具库

npm version license

树形结构处理与参数清理工具库,提供扁平数据转树形、空值过滤、子集ID查询等核心功能,支持TypeScript类型约束,适配多场景数据处理需求。

功能亮点

  • 类型安全:基于TypeScript开发,完整类型定义支持IDE智能提示,避免类型错误
  • 灵活配置:支持自定义字段名(如树形结构的id/parentId/children),适配非标准数据格式
  • 深度处理:支持嵌套对象/数组的递归处理,满足复杂数据结构需求
  • 边界兼容:完善的空值判断与异常处理,确保运行时稳定性

安装

# 使用 pnpm
pnpm add @csir/tools@latest

# 使用 npm
npm install @csir/tools@latest

# 使用 yarn
yarn add @csir/tools@latest

核心功能

1. toTree:扁平数据转树形结构

将包含idparentId的扁平数组转换为嵌套树形结构,支持自定义字段名与根节点规则。

基础用法

import { toTree } from '@csir/tools';

// 扁平数据
const flatData = [
  { id: 1, parentId: 0, name: '根节点' },
  { id: 2, parentId: 1, name: '子节点1' },
  { id: 3, parentId: 1, name: '子节点2' },
  { id: 4, parentId: 2, name: '孙节点1' },
];

// 转换为树形结构
const treeData = toTree(flatData);
/* 结果:
[
  {
    id: 1,
    parentId: 0,
    name: '根节点',
    children: [
      {
        id: 2,
        parentId: 1,
        name: '子节点1',
        children: [{ id: 4, parentId: 2, name: '孙节点1' }] // 无子节点,无 children 字段
      },
      { id: 3, parentId: 1, name: '子节点2' } // 无子节点,无 children 字段
    ]
  }
]
*/

自定义配置

// 自定义字段名(适用于非标准id/parentId字段的数据)
const customData = [
  { uid: 'a', pid: 'root', label: '节点A' },
  { uid: 'b', pid: 'a', label: '节点B' },
];

const customTree = toTree(customData, {
  id: 'uid',         // 用uid作为唯一标识
  parentId: 'pid',   // 用pid作为父节点标识
  children: 'kids',  // 子节点数组字段名为kids
  rootValue: 'root', // parentId为'root'的作为根节点
});
/* 结果:
[
  {
    uid: 'a',
    pid: 'root',
    label: '节点A',
    kids: [{ uid: 'b', pid: 'a', label: '节点B', kids: [] }]
  }
]
*/

配置项说明

| 参数名 | 类型 | 默认值 | 说明 | | ----------- | --------- | ------------ | -------------------------------------------- | | id | keyof T | 'id' | 节点唯一标识字段名 | | parentId | keyof T | 'parentId' | 父节点标识字段名 | | children | string | 'children' | 子节点数组的字段名(自定义字符串) | | rootValue | any | 0 | 根节点的parentId值(匹配此值的节点作为根) |

说明:仅当节点存在子节点时,才会自动添加 children 字段(无子节点的节点不包含该字段),避免冗余

2. cleanParams:清理参数空值

移除对象中的无效值(null/undefined/空字符串),支持深度清理、空数组/对象过滤及字段保留。

基础用法

import { cleanParams } from '@csir/tools';

const rawParams = {
  page: 1,
  size: undefined,
  keyword: '',
  filter: null,
  status: 'active',
};

// 基础清理(移除null/undefined/空字符串)
const cleaned = cleanParams(rawParams);
// 结果:{ page: 1, status: 'active' }

深度清理

const nestedParams = {
  user: {
    name: '',
    age: null,
    address: { city: 'beijing', street: undefined },
  },
  hobbies: [],
  tags: ['', 'js'],
};

// 深度清理嵌套对象和数组
const deepCleaned = cleanParams(nestedParams, {
  deep: true,                  // 开启深度清理
  removeEmptyArrays: true,     // 移除空数组
  preserveKeys: ['user.name'], // 保留user.name(即使为空)
});
/* 结果:
{
  user: {
    name: '', // 被preserveKeys保留
    address: { city: 'beijing' } // 移除了undefined的street
  },
  tags: ['js'] // 过滤了空字符串元素
}
*/

配置项说明

| 参数名 | 类型 | 默认值 | 说明 | | -------------------- | ---------- | ------- | --------------------------------------------- | | deep | boolean | false | 是否深度清理嵌套对象/数组 | | removeEmptyArrays | boolean | false | 清理后若数组为空,是否移除该数组 | | removeEmptyObjects | boolean | false | 清理后若对象为空,是否移除该对象 | | preserveKeys | string[] | [] | 需保留的字段(支持嵌套路径,如'user.name') |

3. findIds:查找树形结构中指定节点的所有后代ID

递归遍历树形结构,获取目标节点及所有后代节点的id(含所有层级)。

基础用法

import { findIds } from '@csir/tools';

// 树形数据
const tree = [
  {
    id: 1,
    children: [
      { id: 2, children: [{ id: 3 }, { id: 4 }] },
      { id: 5 },
    ],
  },
  { id: 6 },
];

// 查找id=1的所有后代ID
const descendantIds = findIds(tree, 1);
// 结果:[1, 2, 3, 4, 5]

自定义字段名

const customTree = [
  {
    uid: 'a',
    kids: [
      { uid: 'b', kids: [{ uid: 'c' }] },
    ],
  },
];

// 自定义id和children字段名
const ids = findIds(customTree, 'a', {
  id: 'uid',     // 用uid作为ID字段
  children: 'kids', // 用kids作为子节点字段
});
// 结果:['a', 'b', 'c']

配置项说明

| 参数名 | 类型 | 默认值 | 说明 | | ---------- | --------- | ------------ | ------------------ | | id | keyof T | 'id' | 节点唯一标识字段名 | | children | keyof T | 'children' | 子节点数组的字段名 |

类型支持

所有函数均提供完整TypeScript类型定义,自动推导输入输出类型,核心类型包括:

  • TreeOptions<T, C extends string = 'children'>:`树形转换配置项:children 字段名限定为字符串
  • CleanParamsOptions:参数清理配置项类型
  • TreeNode<T, C extends string = 'children'>:树形节点类型:继承原数据 T,附加 children 字段(子节点数组,可选)

兼容性

  • 支持Node.js 14+及现代浏览器环境
  • 同时提供CommonJS和ESM模块规范的产物

许可证

MIT