如何解决如何使用迭代的结果重新迭代?
我需要根据条件从另一个数组创建一个新数组: 例如来自一个数组
mainArr: [
{
"id":1,"name":"root"
},{
"id":2,"parentId":1,"name":"2"
},{
"id":148,"parentId":2,"name":"3"
},{
"id":151,"parentId":148,"name":"4"
},{
"id":152,"parentId":151,"name":"5"
}
]
我需要创建一个数组 ['1','2','148','151']
,这意味着从“parentId”到“id”的路径:152 - (此函数的参数)。
我认为主要逻辑可以是这样的:
const parentsArr = [];
mainArr.forEach((item) => {
if (item.id === id) {
parentsArr.unshift(`${item.parentId}`);
}
并且结果 {item.parentId}
应该用于再次迭代。但我不明白该怎么做...
解决方法
您可以为此使用递归函数。首先,您可以将数组转换为 Map,其中每个对象的每个 id 都指向其对象。这样做可以让您有效地 .get()
具有给定 id 的对象。对于每个对象,您都可以获得 parentId,如果已定义,则再次运行您的 traverse()
对象以搜索父 id。当你再也找不到 parentid 时,你就在 root 处,这意味着你可以返回一个空数组来表示不存在 parentid 对象:
const arr = [{"id":1,"name":"root"},{"id":2,"parentId":1,"name":"2"},{"id":148,"parentId":2,"name":"3"},{"id":151,"parentId":148,"name":"4"},{"id":152,"parentId":151,"name":"5"}];
const transform = arr => new Map(arr.map((o) => [o.id,o]));
const traverse = (map,id) => {
const startObj = map.get(+id);
if("parentId" in startObj)
return [...traverse(map,startObj.parentId),startObj.parentId];
else
return [];
}
console.log(traverse(transform(arr),"152"));
如果您想在结果中包含“152”,您可以将递归函数更改为使用 id
参数,并将基本情况更改为返回 [id]
(注意 {{ id 前面的 1}} 用于将其转换为数字(如果是字符串):
+
我将首先使用 reduce
var byId = data.reduce( (acc,i) => {
acc[i.id] = i
return acc;
},{});
然后只需使用循环并将 id 推送到结果数组
var item = byId[input];
var result = []
while(item.parentId) {
result.push(item.parentId)
item = byId[item.parentId];
}
现场示例:
const input = 152;
const data = [ { "id":1,"name":"root" },{ "id":2,"name":"2" },{ "id":148,"name":"3" },{ "id":151,"name":"4" },{ "id":152,"name":"5" } ]
var byId = data.reduce( (acc,{});
var item = byId[input];
var result = []
while(item.parentId) {
result.push(item.parentId)
item = byId[item.parentId];
}
console.log(result.reverse());
尝试更改此行
parentsArr.unshift(`${item.parentId}`);
为此
parentsArr.push(`${item.parentId}`);
那就试试
console.log(parentsArr);
,
这就是我的结局。基本上混合了 Janek 和 Nicks 的答案。只需两步:
- 将代码转换为地图。
- 用一个小函数提取ancester_id
let data = [
{"id":1,"name":"5"}
];
data = data.reduce( (acc,value) => {
// could optionally filter out the id here
return acc.set(value.id,value)
},new Map());
function extract_ancestors( data,id ) {
let result = [];
while( data.get( id ).parentId ) {
id = data.get( id ).parentId;
result.push(id)
}
return result;
}
// some visual tests
console.log( extract_ancestors( data,152 ) );
console.log( extract_ancestors( data,148 ) );
console.log( extract_ancestors( data,1 ) );
PS:我的 OOP 倾向从此开始变得很痒,哈哈。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。