const items = [
{ id: 'item1',
children: [
{ id: 'item1-1',
children: [
{ id: 'item1-1-1' },
{ id: 'item1-1-2' },
{ id: 'item1-1-3'
children: [
{ id: 'item1-1-3-1'}
]
},
]
},
{ id: 'item1-2',
children: [
{ id: 'item1-2-1' }
]
}
]
},
{ id: 'item2' }
]
我想要的如下所示,
function getFullDepthOfObject(){
...
}
getFullIndexOfObject('item1') =====> return '1'
getFullIndexOfObject('item1-2') =====> return '1-2'
getFullIndexOfObject('item1-1-1') =====> return '1-1-1'
getFullIndexOfObject('item1-1-2') =====> return '1-1-2'
getFullIndexOfObject('item2') ===> return '2'
我已经为这太多的时间而苦苦挣扎,但是我做不到。我认为我应该堆叠每个parent
索引,但是我不知道如何获取其父项。有办法吗?
不解析id
字符串。每个id都有随机字符串。像item1-2
这样的id可以简化演示。
我认为我的方法太冗长了... 我尝试过...
// Get Full Index of item1-1
// First, get the target's depth.
var depth = 0;
function getDepthOfId(object, id) {
var level;
if (object.id === id) return 1;
object.children && object.children.some(o => level = getDepthOfId(o, id));
return level && level + 1;
}
depth = getDepthOfId(items[0], 'item1-1');
console.log('depth === ', depth)
// Then, iterate recursively with length of depth.
var indexStacks = [];
function getNestedIndexOfId(obj, id, index) {
if (obj.id === id) {
indexStacks = [index, ...indexStacks]
return index;
}
if (obj.children) {
depth++;
obj.children.map((child, i) => {
getNestedIndexOfId(child, id, i)
})
}
}
// I can get the inner index, but I can't get its parent id.
// I don't know how to this..
function getParentId(obj, id){
// ...?
var parentId;
return parentId;
}
for(var i=0; i<depth; i++){
getNestedIndexOfId('...')
}
// full path will be
indexStacks.join('-')
答案 0 :(得分:2)
const items = [
{ id: 'item1',
children: [
{ id: 'item1-1',
children: [
{ id: 'item1-1-1' },
{ id: 'item1-1-2' },
{ id: 'item1-1-3',
children: [
{ id: 'item1-1-3-1'}
]
}
]
},
{ id: 'item1-2',
children: [
{ id: 'item1-2-1' }
]
}
]
},
{ id: 'item2' }
];
const searchIt = (node, search, path = '', position = 0) => {
if (node.id && node.id === search) {return path !== '' ? `${path}-${position}` : position;}
if (!node.children) {return false}
const index = node.children.findIndex((x) => x.id && x.id === search);
if (index >= 0) {
return path !== '' ? `${path}-${index + 1}` : index + 1;
}
for (let i = 0; i < node.children.length; i++) {
const result = searchIt(node.children[i], search, path !== '' ? `${path}-${i+1}` : i + 1, i);
if (result){
return result;
}
}
return false;
};
console.log(searchIt({children: items}, 'item1-1'));
console.log(searchIt({children: items}, 'item1-1-1'));
console.log(searchIt({children: items}, 'item1-1-2'));
console.log(searchIt({children: items}, 'item1-1-3'));
console.log(searchIt({children: items}, 'item1-1-3-1'));
console.log(searchIt({children: items}, 'item1-2-1'));
console.log(searchIt({children: items}, 'item1-1-3-2'));
console.log(searchIt({children: items}, 'item1-2-2'));
console.log(searchIt({children: items}, 'item3'));
答案 1 :(得分:1)
您可以采用递归和迭代的方法。找到后,路径从最内部的对象返回到函数的外部调用。
function getPath(array, id) {
var result;
array.some((o, i) => {
var temp;
if (o.id === id) return result = `${i + 1}`;
if (temp = getPath(o.children || [], id)) return result = `${i + 1}-${temp}`;
});
return result;
}
const items = [{ id: 'item1', children: [{ id: 'item1-1', children: [{ id: 'item1-1-1' }, { id: 'item1-1-2' }, { id: 'item1-1-3', children: [{ id: 'item1-1-3-1'}] }] }, { id: 'item1-2', children: [{ id: 'item1-2-1' }] }] }, { id: 'item2' }];
console.log(getPath(items, 'item1')); // '1'
console.log(getPath(items, 'item1-2')); // '1-2'
console.log(getPath(items, 'item1-1-1')); // '1-1-1'
console.log(getPath(items, 'item1-1-2')); // '1-1-2'
console.log(getPath(items, 'item2')); // '2'
答案 2 :(得分:0)
您可以使用递归解决此问题。我已经编辑了代码块,并将其制成了可测试的代码段。我不得不纠正您的数据中的错误(缺少逗号或不记得的内容)。
const items = [
{ id: 'itemA',
children: [
{ id: 'item1-1',
children: [
{ id: 'item1-1-1' },
{ id: 'item1-1-2' },
{ id: 'item1-1-3', children: [ { id: 'item1-1-3-1'} ] },
]
},
{ id: 'item1-2', children: [ { id: 'item1-2-1' } ] },
],
},
{ id: 'item2' }
];
const getItemLevel = (targetKey, item, depth = 0) => {
if (item.id === targetKey) return depth;
let foundLevel = null;
if (item.children) {
item.children.forEach((child) => {
if (foundLevel) return;
foundLevel = getItemLevel(targetKey, child, depth +1);
})
}
return foundLevel;
}
console.log(getItemLevel('item1-1-1', { id:'root', children: items }));
console.log(getItemLevel('item2', { id:'root', children: items }));
console.log(getItemLevel('item1-1-3-1', { id:'root', children: items }));
console.log(getItemLevel('keydoesnotexist', { id:'root', children: items }));
答案 3 :(得分:0)
一种简单的方法:
const recursiveFind = (arr, id, res = {indexes: [], found: false}) => {
if (!Array.isArray(arr)) return res
const index = arr.findIndex(e => e.id === id)
if (index < 0) {
for (let i = 0; i < arr.length; i++) {
res.indexes.push(i+1)
const childIndexes = recursiveFind(arr[i].children, id, res)
if (childIndexes.found){
return childIndexes
}
}
}
else {
res.found = true
res.indexes.push(index+1)
}
return res
}
recursiveFind(items, 'item1-1-2').indexes.join('-')
答案 4 :(得分:0)
如果可以使用Lodash + Deepdash,则:
let path;
_.eachDeep(items,(val,key,parent,context)=>{
if(path) return false;
if(val.id=='item1-1-2'){
path=context.path;
return false;
}
},{tree:true,pathFormat:'array'});
console.log(_(path).without('children').map(v=>parseInt(v)+1).join('-'));