@yelon/util
Version:
Universal toolset of ng-yunzai.
287 lines (283 loc) • 9.61 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { YunzaiConfigService } from '@yelon/util/config';
import { NzTreeNode } from 'ng-zorro-antd/core/tree';
class ArrayService {
cogSrv = inject(YunzaiConfigService);
c;
constructor() {
this.c = this.cogSrv.merge('utilArray', {
deepMapName: 'deep',
parentMapName: 'parent',
idMapName: 'id',
parentIdMapName: 'parent_id',
childrenMapName: 'children',
titleMapName: 'title',
checkedMapname: 'checked',
selectedMapname: 'selected',
expandedMapname: 'expanded',
disabledMapname: 'disabled'
});
}
/**
* Convert tree structure to array structure
*
* 将树结构转换成数组结构
*/
treeToArr(tree, options) {
const opt = {
deepMapName: this.c.deepMapName,
parentMapName: this.c.parentMapName,
childrenMapName: this.c.childrenMapName,
clearChildren: true,
cb: null,
...options
};
const result = [];
const inFn = (list, parent, deep = 0) => {
for (const i of list) {
i[opt.deepMapName] = deep;
i[opt.parentMapName] = parent;
if (opt.cb) {
opt.cb(i, parent, deep);
}
result.push(i);
const children = i[opt.childrenMapName];
if (children != null && Array.isArray(children) && children.length > 0) {
inFn(children, i, deep + 1);
}
if (opt.clearChildren) {
delete i[opt.childrenMapName];
}
}
};
inFn(tree, null);
return result;
}
/**
* Convert array structure to tree structure
*
* 数组转换成树数据
*/
arrToTree(arr, options) {
if (!Array.isArray(arr) || arr.length === 0) {
return [];
}
const opt = {
idMapName: this.c.idMapName,
parentIdMapName: this.c.parentIdMapName,
childrenMapName: this.c.childrenMapName,
cb: null,
...options
};
const tree = [];
const childrenOf = {};
let rootPid = opt.rootParentIdValue;
const arrType = arr;
if (!rootPid) {
const pids = arrType.map(i => i[opt.parentIdMapName]);
const emptyPid = pids.findIndex(w => w == null);
rootPid = emptyPid !== -1 ? pids[emptyPid] : pids.sort()[0];
}
for (const item of arrType) {
const id = item[opt.idMapName];
const pid = item[opt.parentIdMapName];
childrenOf[id] = childrenOf[id] || [];
item[opt.childrenMapName] = childrenOf[id];
if (opt.cb) {
opt.cb(item);
}
if (pid !== rootPid) {
childrenOf[pid] = childrenOf[pid] || [];
childrenOf[pid].push(item);
}
else {
tree.push(item);
}
}
return tree;
}
/**
* 数组转换成 `nz-tree` 数据源,通过 `options` 转化项名,也可以使用 `options.cb` 更高级决定数据项
*/
arrToTreeNode(arr, options) {
const opt = {
idMapName: this.c.idMapName,
parentIdMapName: this.c.parentIdMapName,
titleMapName: this.c.titleMapName,
isLeafMapName: 'isLeaf',
checkedMapname: this.c.checkedMapname,
selectedMapname: this.c.selectedMapname,
expandedMapname: this.c.expandedMapname,
disabledMapname: this.c.disabledMapname,
cb: null,
...options
};
const tree = this.arrToTree(arr, {
idMapName: opt.idMapName,
parentIdMapName: opt.parentIdMapName,
childrenMapName: 'children'
});
this.visitTree(tree, (item, parent, deep) => {
item.key = item[opt.idMapName];
item.title = item[opt.titleMapName];
item.checked = item[opt.checkedMapname];
item.selected = item[opt.selectedMapname];
item.expanded = item[opt.expandedMapname];
item.disabled = item[opt.disabledMapname];
if (item[opt.isLeafMapName] == null) {
item.isLeaf = item.children.length === 0;
}
else {
item.isLeaf = item[opt.isLeafMapName];
}
if (opt.cb) {
opt.cb(item, parent, deep);
}
});
return tree.map(node => new NzTreeNode(node));
}
/**
* 递归访问整个树
*/
visitTree(tree, cb, options) {
options = {
childrenMapName: this.c.childrenMapName,
...options
};
const inFn = (data, parent, deep) => {
for (const item of data) {
cb(item, parent, deep);
const childrenVal = item[options.childrenMapName];
if (Array.isArray(childrenVal) && childrenVal.length > 0) {
inFn(childrenVal, item, deep + 1);
}
}
};
inFn(tree, null, 1);
}
/**
* Return the value of the first tree value in the tree where predicate is true, and `undefined` otherwise
*
* 根据条件返回树的第一个值,否则返回 `undefined`
*/
findTree(tree, predicate, options) {
let res;
this.visitTree(tree, item => {
if (res === undefined && predicate(item)) {
res = item;
}
}, options);
return res;
}
/**
* 获取所有已经选中的 `key` 值
*/
getKeysByTreeNode(tree, options) {
const opt = {
includeHalfChecked: true,
...options
};
const keys = [];
this.visitTree(tree, (item, parent, deep) => {
if (item.isChecked || (opt.includeHalfChecked && item.isHalfChecked)) {
keys.push(opt.cb ? opt.cb(item, parent, deep) : opt.keyMapName ? item.origin[opt.keyMapName] : item.key);
}
});
return keys;
}
baseFlat(array, depth, result = []) {
let index = -1;
while (++index < array.length) {
const value = array[index];
if (depth > 0 && Array.isArray(value)) {
if (depth > 1) {
this.baseFlat(value, depth - 1, result);
}
else {
let pushIndex = -1;
const offset = result.length;
while (++pushIndex < value.length) {
result[offset + pushIndex] = value[pushIndex];
}
}
}
else {
result[result.length] = value;
}
}
return result;
}
/**
* Recursively flattens array
*
* 递归扁平数组
* ```ts
* srv.flat([1, [2, 3, [4, 5, [6]]]]) => [1,2,3,4,5,6]
* srv.flat([1, [2, 3, [4, 5, [6]]]], 1) => [1,2,3,[4, 5, [6]]]
* ```
*/
flat(array, depth = 1 / 0) {
return Array.isArray(array) ? this.baseFlat(array, depth) : array;
}
/**
* Group the array
*
* 对数组进行分组
* ```ts
* srv.groupBy([6.1, 4.2, 6.3], Math.floor) => {"4":[4.2],"6":[6.1,6.3]}
* srv.groupBy(['one', 'two', 'three'], v => v.length) => {"3":["one","two"],"5":["three"]}
* ```
*/
groupBy(array, iteratee) {
if (!Array.isArray(array)) {
return {};
}
return array.reduce((result, value) => {
const key = iteratee(value);
if (Object.prototype.hasOwnProperty.call(result, key)) {
result[key].push(value);
}
else {
result[key] = [value];
}
return result;
}, {});
}
/**
* Creates a duplicate-free version of an array
*
* 创建去重后的数组
* ```ts
* uniq([1, 2, 2, 3, 1]) => [1,2,3]
* uniq([{ a: 1 }, { a: 1 }, { a: 2 }], 'a') => [{"a":1},{"a":2}]
* uniq([{ a: 1 }, { a: 1 }, { a: 2 }], i => (i.a === 1 ? 'a' : 'b')) => [{"a":1},{"a":2}]
* ```
*/
uniq(array, predicate) {
return Array.from(array
.reduce((map, value) => {
const key = predicate
? typeof predicate === 'string'
? value[predicate]
: predicate(value)
: value;
if (!map.has(key)) {
map.set(key, value);
}
return map;
}, new Map())
.values());
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ArrayService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ArrayService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ArrayService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [] });
/**
* Generated bundle index. Do not edit.
*/
export { ArrayService };
//# sourceMappingURL=array.mjs.map