数组扁平化
function flatter(arr){
while(arr.some(Array.isArray)){
arr = [].concat(...arr)
}
}
function flatter(arr){
return arr.reduce( (pre,cur) => {
Array.isArray(cur)?[...pre,...flatter(cur)]:[...pre,cur]
},[])
}
Array.prototype.flat = function(){
return [].concat(...this.map( item => (Array.isArray(item)?item.flat():item)))
}
function flatter(arr){
let arrs = []
arr.map(item => {
if(Array.isArray(item){
arrs.push(...flatter(item))
}else {
arrs.push(item)
}
})
return arrs
}
/**
* 迭代实现
*/
function flatten(arr) {
let arrs =[...arr]
let newArr = [];
while (arrs.length){
let item = arrs.shift()
if(Array.isArray(item)){
arrs.unshift(...item)
}else {
newArr.push(item)
}
}
return newArr
}
[1,[2,3,[4,5]],8].join(',').split(',').map(item => Number(item));
实现new构造函数
- 创建了一个新对象(是Object类型的数据)
- 将this指向新对象
- 将创建的对象的原型指向构造函数的原型
- 返回一个对象(如果构造函数本身有返回值且是对象类型,就返回本身的返回值,如果没有才返回新对象)
function _new(fn,arg){
const obj = Object.create(fn.prototype)
const ret = fn.apply(obj,arg)
return ret instanceof Object ? ret : obj
}
function _new(){
const obj = Object.create(null)
const Fn = [].shift.call(arguments)
//通过apply将this指向由Fn变为obj
const ret = Fn.apply(obj,arguments)
// 3、将新对象的原型指向构造函数的原型
obj.__proto__ = Fn.prototype
return Object.prototype.call(ret) === '[object Object]' ? ret : obj
}
扁平数据转Tree
测试数据
const data =
[
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:16',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 100,
'pid': 0,
'ancestors': '0',
'deptName': '若依科技',
'orderNum': '0',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:16',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 110,
'pid': 0,
'ancestors': '0',
'deptName': '鸿星尔克',
'orderNum': '0',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:16',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 101,
'pid': 100,
'ancestors': '0,100',
'deptName': '深圳总公司',
'orderNum': '1',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:16',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 102,
'pid': 100,
'ancestors': '0,100',
'deptName': '长沙分公司',
'orderNum': '2',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:16',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 103,
'pid': 101,
'ancestors': '0,100,101',
'deptName': '研发部门',
'orderNum': '1',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 104,
'pid': 101,
'ancestors': '0,100,101',
'deptName': '市场部门',
'orderNum': '2',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 105,
'pid': 101,
'ancestors': '0,100,101',
'deptName': '测试部门',
'orderNum': '3',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 106,
'pid': 101,
'ancestors': '0,100,101',
'deptName': '财务部门',
'orderNum': '4',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 107,
'pid': 101,
'ancestors': '0,100,101',
'deptName': '运维部门',
'orderNum': '5',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 108,
'pid': 102,
'ancestors': '0,100,102',
'deptName': '市场部门',
'orderNum': '1',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
},
{
'searchValue': null,
'createBy': 'admin',
'createTime': '2021-04-06 03:56:17',
'updateBy': null,
'updateTime': null,
'remark': null,
'params': {},
'id': 109,
'pid': 102,
'ancestors': '0,100,102',
'deptName': '财务部门',
'orderNum': '2',
'leader': '若依',
'phone': '15888888888',
'email': 'ry@qq.com',
'status': '0',
'delFlag': '0',
'parentName': null
}
]
方式1 参考
const buildTree = (itemArray, { id = 'id', parentId = 'parentId', children = 'children', topLevelId = '0' } = {}) => {
const parentMap = new Map(); // 临时存储所有父级
const topLevelResult = []; // 存储顶层结果
for(let item of itemArray) {
if(!parentMap.has(item[id])) {
item[children] = []
} else {
item[children] = parentMap.get(item[id])[children];
}
parentMap.set(item.id, item)
if(!parentMap.has(item[parentId])) {
parentMap.set(item[parentId], {
[children]: []
});
}
parentMap.get(item[parentId])[children].push(item)
if (String(item[parentId]) === String(topLevelId)) {
topLevelResult.push(item)
}
}
return topLevelResult;
}
方式二 参考
function arrayToTree(items) {
const result = []; // 存放结果集
const itemMap = {}; //
for (const item of items) {
const id = item.id;
const pid = item.pid;
if (!itemMap[id]) {
itemMap[id] = {
children: [],
}
}
itemMap[id] = {
...item,
children: itemMap[id]['children']
}
const treeItem = itemMap[id];
if (pid === 0) {
result.push(treeItem);
} else {
if (!itemMap[pid]) {
itemMap[pid] = {
children: [],
}
}
itemMap[pid].children.push(treeItem)
}
}
return result;
}
方式三
这种方式会直接修改原有的item,多执行几次有可能会出现错误的结果
function arrayToTree(items){
const parentMap = {}
const itemMap = {}
const result = []
for(const item of items){
const {id,pid} = item;
if(parentMap[id]){
item.children = parentMap[id]
}
if(!itemMap[pid]){
(parentMap[pid]||(parentMap[pid]=[])).push(item)
}else{
(itemMap[pid].children || (itemMap[pid].children=[])).push(item)
}
itemMap[id] = item
if(item.pid === 0){
result.push(item)
}
}
return result
}
方式四
这种方式生成的对原有的item不会有影响,而且末端节点不会有空的children属性
function arrayToTree (list, parentId = 0, key = 'id', pkey = 'pid') {
const parentMap = {}
const itemMap = {}
const result = []
for (const item of list) {
const { [key]: id, [pkey]: pid } = item
if (parentMap[id]) {
item.children = parentMap[id]
}
const copyitem = { ...item }
if (!itemMap[pid]) {
(parentMap[pid] || (parentMap[pid] = [])).push(copyitem)
} else {
(itemMap[pid].children || (itemMap[pid].children = [])).push(copyitem)
}
itemMap[id] = copyitem
if (item[pkey] === parentId) {
result.push(copyitem)
}
}
return result
}
方式五
function listToTree2 (list, parentId = 0, key = 'id', pkey = 'pid') {
const treeMap = {}
const result = []
for (const item of list) {
const id = item[key]
const pid = item[pkey]
if (!treeMap[pid]) {
treeMap[pid] = { children: [item] }
} else {
treeMap[pid].children.push(item)
}
if (!treeMap[id]) {
item.children = []
treeMap[id] = item
}
if (pid === parentId) {
result.push(item)
}
}
return result
}
export function listToTree3 (list, parentId = 0, key = 'id', pkey = 'pid') {
const treeMap = {}
const result = []
for (const item of list) {
const id = item[key]
const pid = item[pkey]
const copyItem = { ...item }
if (!treeMap[pid]) {
treeMap[pid] = { children: [copyItem] }
} else {
treeMap[pid].children.push(copyItem)
}
if (!treeMap[id]) {
copyItem.children = []
treeMap[id] = copyItem
}
if (pid === parentId) {
result.push(copyItem)
}
}
return result
}