试图自己解决该任务,但我放弃了。无论我尝试了什么,那都行不通。因此决定在这里寻求帮助。
有一个物体:
var obj = [{
"name": "111",
"type": "folder",
"expanded": true,
"id": 0,
"items": [
{
"name": "222",
"type": "folder",
"expanded": true,
"id": 1,
"items": [
{
"name": "333",
"type": "folder",
"expanded": true,
"id": 2,
"items": [
{
"name": "444",
"type": "folder",
"expanded": true,
"id": 3,
"items": [],
"itemIndex": 0,
"index": 0
}
],
"itemIndex": 0,
"index": 0
}
],
"itemIndex": 0,
"index": 0
}
],
"itemIndex": 0,
"index": 0
}]
深度可能会有所不同,但是每个级别的键集始终相同。 我需要确定最可能的水平。
考虑到上面的代码,比方说,我需要一个功能,即仅具有其 ID
或 name
,可以将另一个对象推入以下对象的“ items”数组中:
{
"name": "444",
"type": "folder",
"expanded": true,
"id": 3,
"items": [],
"itemIndex": 0,
"index": 0
}
换句话说,我有一个输入文本和一个按钮。输入文本并单击该按钮后,函数应确定给定对象的最后一级,然后推送一个新生成的对象(同一组键, ID 应为继承对象的 +1)名称应从输入的文本字段字符串中输入)。
我希望我尽可能详细地解释问题。
答案 0 :(得分:1)
您将需要一个首先找到最深节点的函数:
/**
* Return [depth, item] where item is the deepest subnode of node.
*/
function find_deepest(node, depth=0) {
if (node.items.length === 0) return [depth, node];
return node.items.map(child => find_deepest(child, depth+1)).sort().reverse()[0];
}
那么就很简单:
const [depth, node] = find_deepest(obj, 0);
node.items.push({...});
更新:刚刚意识到您的obj
是一个列表,因此使用上面的代码,它看起来像这样:
const [depth, node] = obj.map(child => find_deepest(child)).sort().reverse()[0]);
这不是最大的界面。
将递归分为两个函数,一个用于节点大小写,一个用于数组大小写,然后将它们包装在一个按类型分支的函数中,将为您提供一个更好的接口:
console.log(find_deepest(obj));
有关详细信息,请参见下面的代码片段(我用另一个带有空项目的分支扩展了您的obj:
var obj = [{
"name": "111", "type": "folder", "expanded": true, "id": 0, "itemIndex": 0, "index": 0,
"items": [{
"name": "222", "type": "folder", "expanded": true, "id": 1, "itemIndex": 0, "index": 0,
"items": [{
"name": "333", "type": "folder", "expanded": true, "id": 2, "itemIndex": 0, "index": 0,
"items": [{
"name": "444", "type": "folder", "expanded": true, "id": 3,"itemIndex": 0, "index": 0,
"items": []
}],
}, {
"name": "555", "type": "folder", "expanded": true, "id": 3,"itemIndex": 0, "index": 0,
"items": [{
"name": "666", "type": "folder", "expanded": true, "id": 3,"itemIndex": 0, "index": 0,
"items": [{
"name": "777", "type": "folder", "expanded": true, "id": 3,"itemIndex": 0, "index": 0,
"items": [],
}]
}]
}]
}]
}];
function find_deepest(val, depth=0) {
function _find_deepest_node(node, depth) {
if (node.items.length === 0) return [depth, node];
return _find_deepest_array(node.items, depth + 1);
}
function _find_deepest_array(arr, depth) {
return arr.map(child => _find_deepest_node(child, depth)).sort().reverse()[0];
}
if (Array.isArray(val)) {
return _find_deepest_array(val, depth)[1]; // get the node, not the depth..
} else {
return _find_deepest_node(val, depth)[1];
}
}
console.log(find_deepest(obj));
答案 1 :(得分:0)
我将创建一个递归函数,一旦找到正确的ID,它将把数据推送到数组的末尾。如果找不到ID,请转到下一项。看起来像这样:
function pushItem(id, data, obj) {
for (let itm of obj) {
let r = itm.items.find(i => i.id == id)
if(!r) return pushItem(id, data, itm.items)
r.items.push(data)
}
}
pushItem(3, {abc: 1}, obj)
console.log(obj)
这是一个有效的示例:
var obj = [{
"name": "111",
"type": "folder",
"expanded": true,
"id": 0,
"items": [{
"name": "222",
"type": "folder",
"expanded": true,
"id": 1,
"items": [{
"name": "333",
"type": "folder",
"expanded": true,
"id": 2,
"items": [{
"name": "444",
"type": "folder",
"expanded": true,
"id": 3,
"items": [],
"itemIndex": 0,
"index": 0
}],
"itemIndex": 0,
"index": 0
}],
"itemIndex": 0,
"index": 0
}],
"itemIndex": 0,
"index": 0
}]
function pushItem(id, data, obj) {
for (let itm of obj) {
let r = itm.items.find(i => i.id == id)
if (!r) return pushItem(id, data, itm.items)
r.items.push(data)
}
}
pushItem(3, { name: "123123", id: 20, items: [] }, obj)
console.log(obj)