-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 125 题:如何将 [{id: 1}, {id: 2, pId: 1}, ...] 的重复数组(有重复数据)转成树形结构的数组 [{id: 1, child: [{id: 2, pId: 1}]}, ...] (需要去重) #243
Comments
[{id: 1}, {id: 2, pId: 1}, ...]
的重复数组(有重复数据)转成树形结构的数组 [{id: 1, child: [{id: 2, pId: 1}]}, ...]
(需要去重)
哈希表,时间复杂度O(n)const fn = arr => {
const res = []
const map = arr.reduce((res, item) => ((res[item.id] = item), res), {})
for (const item of Object.values(map)) {
if (!item.pId) {
res.push(item)
} else {
const parent = map[item.pId]
parent.child = parent.child || []
parent.child.push(item)
}
}
return res
}
// const arr = [{id: 1}, {id:2, pId: 1}, {id: 3, pId: 2}, {id: 4}, {id:3, pId: 2}, {id: 5, pId: 4}]
// fn(arr) => [{id: 1, child: [{id: 2, pId: 1, child: [{ id: 3, pId: 2}]}]}, {id: 4, child: [{id: 5, pId: 4}]}] |
是这个意思吗,不太清楚,轻喷哈
|
var flatLs = [ |
@ZodiacSyndicate 👍 厉害!(提个小建议,最好复制一下对象,否则会修改原数组) const map = arr.reduce((res, item) => ((res[item.id] = Object.assign({}, item)), res), {}) |
const arr = [
{ id: 1, pid: null },
{ id: 2, pid: 1 },
{ id: 3, pid: 1 },
{ id: 4, pid: 2 },
{ id: 5, pid: 2 },
{ id: 6, pid: 3 },
{ id: 7, pid: 3 },
{ id: 8, pid: 3 },
{ id: 9, pid: 8 },
{ id: 10, pid: 6 }
];
function arr2tree(arr = []) {
let rootNode = arr.find(v => v.pid === null);
if (!rootNode) {
throw new Error("Expected rootNode not exists");
}
let rootNodeIndex = arr.findIndex(v => v.pid === null);
arr.splice(rootNodeIndex, 1);
let tree = {
id: rootNode.id,
children: []
};
let map = {};
arr.forEach(v => {
if (!map[v.pid]) {
map[v.pid] = [];
}
map[v.pid].push(v);
});
for (const pid in map) {
let children = map[pid];
children.forEach(child => {
if (map[child.id]) {
child.children = map[child.id];
}
});
}
tree.children = map[rootNode.id];
return tree;
}
const tree = arr2tree(arr); |
function convertToTree(arr) {
const MAP = arr.reduce((res, cur) => res.set(cur.id, cur), new Map());
return [...MAP].reduce((result, [, value]) => {
const { pId } = value;
if (pId === undefined) {
result.push(value)
} else {
const parent = map.get(pId);
parent && (parent.children || (parent.children = [])).push(value);
}
return result;
}, [])
} |
题目都看不懂,pid指父元素的id吗 |
我来写一个
|
const fn = arr => { |
arrayToTree([...new Set(array.map(JSON.stringify))].map(JSON.parse)) function arrayToTree(data, nodesField, idField, parentIdField) {
} |
Object.values(map) 将对象转为数组 |
网站类目管理需求? |
reduce 遍历的时间复杂度不算吗? |
function transformTree(arr) {
let res = [];
let map = arr.reduce((pre, item) => {//去重且进行构建哈希表
pre[item.id] = item;
return pre;
}, {})
console.log(map)
for (let item of Object.values(map)) {
if (!item.pId) {
res.push(item);
} else {
const parent = map[item.pId];
parent.child = parent.child || [];//当这个元素没有时指向一个数组并将该孩子元素增加进去含有有自己孩子时采用本来的child数组,
parent.child.push(item)
}
}
return res;
}
console.log(transformTree(arr)) |
用Markdown语法写就有缩进了 |
Object.values()只是获取对象可枚举属性的value值,返回一个数组 |
const map = arr.reduce((res, item) => ((res[item.id] = item), res), {}) 等同于 const map = {}
arr.forEach((item) => {
map[item.id] = item
}) 我差点还没看懂,太菜了233 |
/**
* @desc
*
* @使用场景
*
* @coder.yang2010@gmail.com
* @Date 2019/8/28
**/
let arr: {id: number; pid?: number}[] = [
{id: 1},
{id: 2, pid: 1},
{id: 3, pid: 2},
{id: 4, pid: 1},
{id: 5, pid: 3},
{id: 6, pid: 2},
{id: 6, pid: 2},
{id: 2, pid: 1},
];
interface IItem {
id: number;
pid?: number;
child?:IItem[];
}
let ItemsMap: {[id: number]: IItem} = {};
let PidItemsMap: {[pid: number]: IItem[]} = {};
for (let entry of arr) {
if(ItemsMap[entry.id] ) {
//去重!!
continue;
}
ItemsMap[entry.id] = entry;
let _pid = entry.pid || 'master';
if (!PidItemsMap[_pid]) {
PidItemsMap[_pid] = [entry];
} else {
PidItemsMap[_pid].push(entry);
}
}
let root = PidItemsMap['master'];
for(let entry of Object.values(ItemsMap)) {
entry.child = PidItemsMap[entry.id];
}
console.log(JSON.stringify(root,null,2)); |
|
function formatArr (arr,newArr = []){
//去重和第一次格式化数组
let idArr = [],obj={}
for(let i=0;i<arr.length;i++){
let val = arr[i]
if(!~idArr.indexOf(val.id)){
idArr.push( val.id )
obj[val.id] = val
!val.pId && newArr.push(val)
}
}
for(let i in obj ){
if(obj[i].pId){
obj[obj[i].pId].children ? obj[ obj[i].pId].children.push(obj[i]) : obj[obj[i].pId].children = [ obj[i] ]
}
}
return newArr
} |
Object.assign是浅拷贝 |
就是应用到了 引用 |
同一个问题? #139 |
const arr = [
{ id: 1, pid: null },
{ id: 2, pid: 1 },
{ id: 3, pid: 1 },
{ id: 2, pid: 1 },
{ id: 4, pid: 2 },
{ id: 5, pid: 2 },
{ id: 6, pid: 3 },
{ id: 7, pid: 3 },
{ id: 8, pid: 3 },
{ id: 9, pid: 8 },
{ id: 10, pid: 6 }
]
// 去重
const deduplication = (arr) => {
return arr.filter((item, index) => index === arr.findIndex(child => item.id === child.id))
}
// 递归嵌套
const arrToTree = (arr, pid = null) => {
return arr.filter(item => item.pid === pid)
.map(item => ({ ...item, children: arrToTree(arr, item.id)}))
}
const solution = (arr) => {
return arrToTree(deduplication(arr))
}
solution(arr) |
利用对象是引用类型,直接通过pId找到父元素
|
function handelFn(arr) {
let obj = {}
let tree = {}
async function ff(i) {
obj[arr[i].pId].child.push(arr[i])
}
for (let i = 0; i < arr.length; i++) {
arr[i].child = []
obj[arr[i].id] = arr[i]
if (!arr[i].pId) {
tree [arr [i].id] = arr [i]
} else {
ff(i)
}
}
return tree
} |
同问,reduce的复杂度 不用算进去么?? |
|
function handelFunc(srcData) { |
const find12 = (arr) => {
} |
|
可行吗?
arr = [{id: 1}, {id: 2, pId: 1}, {id: 3, pId: 2}, {id: 4, pId: 2}, {id: 5, pId: 4}]
…------------------ 原始邮件 ------------------
发件人: "Advanced-Frontend/Daily-Interview-Question" ***@***.***>;
发送时间: 2022年4月13日(星期三) 下午3:03
***@***.***>;
***@***.******@***.***>;
主题: Re: [Advanced-Frontend/Daily-Interview-Question] 第 125 题:如何将 [{id: 1}, {id: 2, pId: 1}, ...] 的重复数组(有重复数据)转成树形结构的数组 [{id: 1, child: [{id: 2, pId: 1}]}, ...] (需要去重) (#243)
const map = arr.reduce((res, item) => { if (!item.pid) { res[item.id] = item } item.child = arr.filter(it => it.pid && it.pid === item.id) return res }, [])
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
No description provided.
The text was updated successfully, but these errors were encountered: