Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@zhengxs/js.tree

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zhengxs/js.tree - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

9

CHANGELOG.md

@@ -0,1 +1,10 @@

# [0.4.0](https://github.com/zhengxs2018/js.tree/compare/v0.3.0...v0.4.0) (2021-07-12)
### Features
* 优先从转换后的数据中获取 id ([70ff07c](https://github.com/zhengxs2018/js.tree/commit/70ff07cfffbe739b7fda2cd7b6bdd9efc4efc69f))
# [0.3.0](https://github.com/zhengxs2018/js.tree/compare/v0.2.0...v0.3.0) (2021-06-14)

@@ -2,0 +11,0 @@

2

dist/index.d.ts

@@ -18,3 +18,3 @@ export type { ID, None, Row, Node, Exporter, Transform, Predicate } from './types';

*/
export declare const version = "0.3.0";
export declare const version = "0.4.0";
//# sourceMappingURL=index.d.ts.map

@@ -240,6 +240,2 @@ 'use strict';

data.forEach((row, i) => {
// 获取节点ID
const id = get(row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 数据结构转换

@@ -250,2 +246,6 @@ const node = transform(row, i);

return;
// 获取节点ID
const id = getId(node, row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 获取子级元素

@@ -262,3 +262,3 @@ const children = childNodes[id];

// 注意: 不能使用 _.get 的 `defaultValue` 参数, 那个只有不存在 `key` 才会返回默认值
const parentId = defaultTo(get(row, parentKey), ROOT_ID);
const parentId = defaultTo(getId(node, row, parentKey), ROOT_ID);
// 获取同级元素

@@ -283,2 +283,10 @@ const siblings = childNodes[parentId];

}
/**
* 优先从 node 中获取 id
* 如果没有再从原始对象中获取
*/
function getId(node, raw, key) {
const id = get(node, key);
return isNil(id) ? get(raw, key) : id;
}

@@ -292,2 +300,185 @@ /**

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -323,3 +514,3 @@ function toTree(data, options = {}) {

*/
const version = '0.3.0';
const version = '0.4.0';

@@ -326,0 +517,0 @@ exports.CHILDREN_KEY = CHILDREN_KEY;

@@ -208,6 +208,2 @@ 'use strict';

data.forEach((row, i) => {
// 获取节点ID
const id = lodash.get(row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 数据结构转换

@@ -218,2 +214,6 @@ const node = transform(row, i);

return;
// 获取节点ID
const id = getId(node, row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 获取子级元素

@@ -230,3 +230,3 @@ const children = childNodes[id];

// 注意: 不能使用 _.get 的 `defaultValue` 参数, 那个只有不存在 `key` 才会返回默认值
const parentId = lodash.defaultTo(lodash.get(row, parentKey), ROOT_ID);
const parentId = lodash.defaultTo(getId(node, row, parentKey), ROOT_ID);
// 获取同级元素

@@ -251,2 +251,10 @@ const siblings = childNodes[parentId];

}
/**
* 优先从 node 中获取 id
* 如果没有再从原始对象中获取
*/
function getId(node, raw, key) {
const id = lodash.get(node, key);
return lodash.isNil(id) ? lodash.get(raw, key) : id;
}

@@ -260,2 +268,185 @@ /**

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -291,3 +482,3 @@ function toTree(data, options = {}) {

*/
const version = '0.3.0';
const version = '0.4.0';

@@ -294,0 +485,0 @@ exports.CHILDREN_KEY = CHILDREN_KEY;

@@ -188,2 +188,185 @@

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -214,4 +397,4 @@ export declare function toTree<S = Node_2, T extends Row = Row>(data: T[], options?: ToTreeOptions<S, T>): S[];

*/
export declare const version = "0.3.0";
export declare const version = "0.4.0";
export { }

@@ -236,6 +236,2 @@ /**

data.forEach((row, i) => {
// 获取节点ID
const id = get(row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 数据结构转换

@@ -246,2 +242,6 @@ const node = transform(row, i);

return;
// 获取节点ID
const id = getId(node, row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 获取子级元素

@@ -258,3 +258,3 @@ const children = childNodes[id];

// 注意: 不能使用 _.get 的 `defaultValue` 参数, 那个只有不存在 `key` 才会返回默认值
const parentId = defaultTo(get(row, parentKey), ROOT_ID);
const parentId = defaultTo(getId(node, row, parentKey), ROOT_ID);
// 获取同级元素

@@ -279,2 +279,10 @@ const siblings = childNodes[parentId];

}
/**
* 优先从 node 中获取 id
* 如果没有再从原始对象中获取
*/
function getId(node, raw, key) {
const id = get(node, key);
return isNil(id) ? get(raw, key) : id;
}

@@ -288,2 +296,185 @@ /**

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -319,4 +510,4 @@ function toTree(data, options = {}) {

*/
const version = '0.3.0';
const version = '0.4.0';
export { CHILDREN_KEY, ID_KEY, PARENT_ID_KEY, ROOT_ID, each, exclude, exporter, filter, map, parse, toRows, toTree, version };

@@ -204,6 +204,2 @@ import { defaultTo, isNil, get } from 'lodash-es';

data.forEach((row, i) => {
// 获取节点ID
const id = get(row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 数据结构转换

@@ -214,2 +210,6 @@ const node = transform(row, i);

return;
// 获取节点ID
const id = getId(node, row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 获取子级元素

@@ -226,3 +226,3 @@ const children = childNodes[id];

// 注意: 不能使用 _.get 的 `defaultValue` 参数, 那个只有不存在 `key` 才会返回默认值
const parentId = defaultTo(get(row, parentKey), ROOT_ID);
const parentId = defaultTo(getId(node, row, parentKey), ROOT_ID);
// 获取同级元素

@@ -247,2 +247,10 @@ const siblings = childNodes[parentId];

}
/**
* 优先从 node 中获取 id
* 如果没有再从原始对象中获取
*/
function getId(node, raw, key) {
const id = get(node, key);
return isNil(id) ? get(raw, key) : id;
}

@@ -256,2 +264,185 @@ /**

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -287,4 +478,4 @@ function toTree(data, options = {}) {

*/
const version = '0.3.0';
const version = '0.4.0';
export { CHILDREN_KEY, ID_KEY, PARENT_ID_KEY, ROOT_ID, each, exclude, exporter, filter, map, parse, toRows, toTree, version };

@@ -204,6 +204,2 @@ import { defaultTo, isNil, get } from 'lodash';

data.forEach((row, i) => {
// 获取节点ID
const id = get(row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 数据结构转换

@@ -214,2 +210,6 @@ const node = transform(row, i);

return;
// 获取节点ID
const id = getId(node, row, idKey);
// id 必须存在
assert(isNotNil(id), `id is required, in ${i}.`);
// 获取子级元素

@@ -226,3 +226,3 @@ const children = childNodes[id];

// 注意: 不能使用 _.get 的 `defaultValue` 参数, 那个只有不存在 `key` 才会返回默认值
const parentId = defaultTo(get(row, parentKey), ROOT_ID);
const parentId = defaultTo(getId(node, row, parentKey), ROOT_ID);
// 获取同级元素

@@ -247,2 +247,10 @@ const siblings = childNodes[parentId];

}
/**
* 优先从 node 中获取 id
* 如果没有再从原始对象中获取
*/
function getId(node, raw, key) {
const id = get(node, key);
return isNil(id) ? get(raw, key) : id;
}

@@ -256,2 +264,185 @@ /**

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/

@@ -287,4 +478,4 @@ function toTree(data, options = {}) {

*/
const version = '0.3.0';
const version = '0.4.0';
export { CHILDREN_KEY, ID_KEY, PARENT_ID_KEY, ROOT_ID, each, exclude, exporter, filter, map, parse, toRows, toTree, version };

@@ -157,7 +157,7 @@ (function (global, factory) {

data.forEach(function (row, i) {
var id = get(row, idKey);
assert(isNotNil(id), "id is required, in " + i + ".");
var node = transform(row, i);
if (isNil(node))
return;
var id = getId(node, row, idKey);
assert(isNotNil(id), "id is required, in " + i + ".");
var children = childNodes[id];

@@ -170,3 +170,3 @@ if (children) {

}
var parentId = defaultTo(get(row, parentKey), ROOT_ID);
var parentId = defaultTo(getId(node, row, parentKey), ROOT_ID);
var siblings = childNodes[parentId];

@@ -189,2 +189,6 @@ if (siblings) {

}
function getId(node, raw, key) {
var id = get(node, key);
return isNil(id) ? get(raw, key) : id;
}

@@ -209,3 +213,3 @@ function toTree(data, options) {

var version = '0.3.0';
var version = '0.4.0';

@@ -212,0 +216,0 @@ exports.CHILDREN_KEY = CHILDREN_KEY;

@@ -15,3 +15,3 @@ !function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((n="undefined"!=typeof globalThis?globalThis:n||self).jsTree={})}(this,(function(n){"use strict";

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */var r=function(){return(r=Object.assign||function(n){for(var r,e=1,t=arguments.length;e<t;e++)for(var o in r=arguments[e])Object.prototype.hasOwnProperty.call(r,o)&&(n[o]=r[o]);return n}).apply(this,arguments)};function e(n){return null==n}function t(n,r){return e(n)?r:n}function o(n,r,e){return t(n[r],e)}var i="__root__",u="parentId",f="children";function c(n,r){var e=n.childNodes;return"function"==typeof r?r(e,n)||[]:e[t(r,i)]||[]}function a(n,r){void 0===r&&(r={});var c=t(r.idKey,"id"),a=t(r.parentKey,u),d=t(r.childrenKey,f),s=t(r.transform,(function(n){return n})),h=t(r.insert,(function(n,r){return n.push(r)})),v={},l={};return n.forEach((function(n,r){var u,f=o(n,c);!function(n,r){if(!n){if(r instanceof Error)throw r;throw new Error(r)}}((u=f,!1===e(u)),"id is required, in "+r+".");var p=s(n,r);if(!e(p)){var y=l[f];y?p[d]=y:l[f]=p[d]=[];var E=t(o(n,a),i),_=l[E];h(_||(l[E]=[]),p),v[f]=p}})),{idKey:c,parentKey:a,childrenKey:d,nodes:v,childNodes:l}}n.CHILDREN_KEY=f,n.ID_KEY="id",n.PARENT_ID_KEY=u,n.ROOT_ID=i,n.each=function(n,r,e){return void 0===e&&(e=f),function n(o,i){return o.forEach((function(o,u){r(o,u,i)||n(t(o[e],[]),i.concat(o))})),[]}(n,[])},n.exclude=function(n,e,o){return void 0===o&&(o=f),function n(i,u){var f=[];return i.forEach((function(i,c){var a;if(!e(i,c,u)){var d=t(i[o],[]);if(0!==d.length){var s=n(d,u.concat(i));s.length>0&&f.push(r(r({},i),((a={})[o]=s,a)))}else f.push(i)}})),f}(n,[])},n.exporter=c,n.filter=function(n,e,o){return void 0===o&&(o=f),function n(i,u){var f=[];return i.forEach((function(i,c){var a;if(e(i,c,u))f.push(r({},i));else{var d=n(t(i[o],[]),u.concat(i));d.length>0&&f.push(r(r({},i),((a={})[o]=d,a)))}})),f}(n,[])},n.map=function(n,e,o){return void 0===o&&(o=f),function n(i,u){return i.map((function(i,f){var c,a=e(r({},i),f,u),d=n(t(a[o],[]),u.concat(i));return d.length>0?r(r({},a),((c={})[o]=d,c)):a}))}(n,[])},n.parse=a,n.toRows=function(n,e){void 0===e&&(e=f);var o=[];return n.forEach((function n(i){var u,f,c,a,d=r({},i),s=(c=[],a=(u=d)[f=e],delete u[f],t(a,c));o.push(d),s.forEach(n)})),o},n.toTree=function(n,r){return void 0===r&&(r={}),c(a(n,r),r.root)},n.version="0.3.0",Object.defineProperty(n,"__esModule",{value:!0})}));
***************************************************************************** */var r=function(){return(r=Object.assign||function(n){for(var r,e=1,t=arguments.length;e<t;e++)for(var o in r=arguments[e])Object.prototype.hasOwnProperty.call(r,o)&&(n[o]=r[o]);return n}).apply(this,arguments)};function e(n){return null==n}function t(n,r){return e(n)?r:n}function o(n,r,e){return t(n[r],e)}var i="__root__",u="parentId",f="children";function c(n,r){var e=n.childNodes;return"function"==typeof r?r(e,n)||[]:e[t(r,i)]||[]}function a(n,r){void 0===r&&(r={});var o=t(r.idKey,"id"),c=t(r.parentKey,u),a=t(r.childrenKey,f),s=t(r.transform,(function(n){return n})),h=t(r.insert,(function(n,r){return n.push(r)})),v={},l={};return n.forEach((function(n,r){var u=s(n,r);if(!e(u)){var f,p=d(u,n,o);!function(n,r){if(!n){if(r instanceof Error)throw r;throw new Error(r)}}((f=p,!1===e(f)),"id is required, in "+r+".");var y=l[p];y?u[a]=y:l[p]=u[a]=[];var E=t(d(u,n,c),i),_=l[E];h(_||(l[E]=[]),u),v[p]=u}})),{idKey:o,parentKey:c,childrenKey:a,nodes:v,childNodes:l}}function d(n,r,t){var i=o(n,t);return e(i)?o(r,t):i}n.CHILDREN_KEY=f,n.ID_KEY="id",n.PARENT_ID_KEY=u,n.ROOT_ID=i,n.each=function(n,r,e){return void 0===e&&(e=f),function n(o,i){return o.forEach((function(o,u){r(o,u,i)||n(t(o[e],[]),i.concat(o))})),[]}(n,[])},n.exclude=function(n,e,o){return void 0===o&&(o=f),function n(i,u){var f=[];return i.forEach((function(i,c){var a;if(!e(i,c,u)){var d=t(i[o],[]);if(0!==d.length){var s=n(d,u.concat(i));s.length>0&&f.push(r(r({},i),((a={})[o]=s,a)))}else f.push(i)}})),f}(n,[])},n.exporter=c,n.filter=function(n,e,o){return void 0===o&&(o=f),function n(i,u){var f=[];return i.forEach((function(i,c){var a;if(e(i,c,u))f.push(r({},i));else{var d=n(t(i[o],[]),u.concat(i));d.length>0&&f.push(r(r({},i),((a={})[o]=d,a)))}})),f}(n,[])},n.map=function(n,e,o){return void 0===o&&(o=f),function n(i,u){return i.map((function(i,f){var c,a=e(r({},i),f,u),d=n(t(a[o],[]),u.concat(i));return d.length>0?r(r({},a),((c={})[o]=d,c)):a}))}(n,[])},n.parse=a,n.toRows=function(n,e){void 0===e&&(e=f);var o=[];return n.forEach((function n(i){var u,f,c,a,d=r({},i),s=(c=[],a=(u=d)[f=e],delete u[f],t(a,c));o.push(d),s.forEach(n)})),o},n.toTree=function(n,r){return void 0===r&&(r={}),c(a(n,r),r.root)},n.version="0.4.0",Object.defineProperty(n,"__esModule",{value:!0})}));
//# sourceMappingURL=js.tree.min.js.map

@@ -19,4 +19,187 @@ import type { ID, Row, Node, Exporter } from '../types';

* @param options - 配置项
*
* @example <caption>默认</caption>
*
* ```js
* toTree([
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ])
* // ->
* [
* {
* id: 1,
* parentId: null,
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: null, children: [] },
* ]
* ```
*
* @example <caption>自定义 id/parentId 属性</caption>
*
* ```js
* toTree(
* [
* { sub: 1, parent: null },
* { sub: 2, parent: null },
* { sub: 3, parent: 1 },
* ],
* { idKey: 'sub', parentKey: 'parent' }
* )
* // ->
* [
* {
* sub: 1,
* parent: null,
* items: [
* { sub: 3, parent: 1, items: [] }
* ]
* },
* { sub: 2, parent: null, items: [] },
* ]
* ```
*
* @example <caption>自定义 children 属性</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* { children: 'items' }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* items: [
* { id: 3, parentId: 1, items: [] }
* ]
* },
* { id: 2, parentId: null, items: [] },
* ]
* ```
*
* @example <caption>自定义根节点</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: '__root__' }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>自定义函数导出</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: '__root__' },
* { id: 2, parentId: '__root__' },
* { id: 3, parentId: 1 },
* ],
* { root: nodes => nodes['__root__'] }
* )
* // ->
* [
* {
* id: 1,
* parentId: '__root__',
* children: [
* { id: 3, parentId: 1, children: [] }
* ]
* },
* { id: 2, parentId: '__root__', children: [] },
* ]
* ```
*
* @example <caption>数据转换</caption>
*
* ```js
* toTree(
* [
* { id: 1, parentId: null },
* { id: 2, parentId: null },
* { id: 3, parentId: 1 },
* ],
* {
* transform(row) {
* // 返回 null 或 undefined 的数据不回保留
* if (row.id === 3) return
* // 可以进行浅拷贝后修改,防止破坏原始对象
* return { ...row, test: true }
* }
* }
* )
* // ->
* [
* { id: 1, parentId: null, test: true, children: [] },
* { id: 2, parentId: null, test: true, children: [] },
* ]
* ```
*
* @example <caption>自定义插入顺序</caption>
*
* ```js
* toTree(
* [
* { id: 2, parentId: null, sort: 2 },
* { id: 5, parentId: 1, sort: 1 },
* { id: 4, parentId: 1, sort: 2 },
* { id: 3, parentId: null, sort: 3 },
* { id: 1, parentId: null, sort: 1 },
* ],
* {
* insert(siblings, node) {
* // ps: 任意层级的数据都是这样处理的
* const index = siblings.findIndex((n) => n.sort > node.sort)
*
* // 根据位置选择插入到兄弟节点当中
* if (index === -1) {
* siblings.push(node)
* } else {
* siblings.splice(index, 0, node)
* }
* }
* }
* )
* // ->
* [
* {
* id: 1,
* parentId: null,
* sort: 1
* children: [
* { id: 4, parentId: null, sort: 1, children: [] },
* { id: 5, parentId: null, sort: 2, children: [] },
* ]
* },
* { id: 2, parentId: null, sort: 2, children: [] },
* { id: 3, parentId: null, sort: 3, children: [] },
* ]
* ```
*/
export declare function toTree<S = Node, T extends Row = Row>(data: T[], options?: ToTreeOptions<S, T>): S[];
//# sourceMappingURL=toTree.d.ts.map
{
"name": "@zhengxs/js.tree",
"version": "0.3.0",
"version": "0.4.0",
"description": "快速,轻量,无依赖的树结构数据处理函数库",

@@ -28,4 +28,4 @@ "main": "./dist/js.tree.common.js",

"api": "api-extractor run",
"typedoc": "typedoc",
"commit": "cz",
"doc": "typedoc",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",

@@ -35,3 +35,4 @@ "preversion": "npm run lint && npm test",

"postversion": "git push --follow-tags",
"prepublishOnly": "npm run build && npm run api"
"prepublishOnly": "npm run build && npm run api",
"postpublish": "typedoc && gh-pages -d ./dist-doc -t"
},

@@ -92,2 +93,3 @@ "publishConfig": {

"eslint-plugin-tsdoc": "^0.2.14",
"gh-pages": "^3.2.0",
"husky": "^6.0.0",

@@ -94,0 +96,0 @@ "jest": "^26.6.3",

@@ -64,5 +64,2 @@ <div align="center">

快速,轻量,无依赖的树结构数据处理函数库。
- 一个循环解决行转树的问题

@@ -199,3 +196,3 @@ - 转树除了添加 `children` 属性,不会修改任何数据

[Try in runkit](https://npm.runkit.com/@zhengxs/bem)
[Try in runkit](https://npm.runkit.com/@zhengxs/js.tree)

@@ -202,0 +199,0 @@ ## TypeScript

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc