对象数组中的递归循环
recursive loop in objects arrays
我正在使用可能如下所示的结构:
var data = {
"name": "McLaren",
"drivers": [{
"name": "BMW",
"drivers": [{
"name": "Subaru",
"drivers": [{
"name": "Saab",
"drivers": [{
"name": "Lexus",
"drivers": []
}, {
"name": "Honda",
"drivers": []
}]
}]
}]
}]
}
它是一个包含name
和drivers
数组的对象。 drivers
可以是空的,但它始终存在。
现在假设我有以下对象:
{
"name": "KIA",
"drivers":[]
}
我需要将此对象放置在正确的位置。在我的帮助下,我得到了以下内容:
McLaren/BMW/Subaru/saab
因此,新对象应推送到与雷克萨斯和本田相同的阵列。
我一直在疯狂地试图弄清楚如何做到这一点。我一直在思考以下几行:
我将路径转换为数组:
var pathArr = ["McLaren","BMW","Subaru","saab"]
并尝试使用递归函数:
myFunction(newObject){
for (var i = 0; i < pathArr.length; i++) {
recursiveFunc(data.drivers, pathArr[i] )
}
var recursiveFunc(driversArr, name) {
for (var ix = 0; ix < driversArr.length; ix++) {
if (driversArr[ix].name === name) {
recursiveFunc(driversArr[ix].drivers, "HERE I NEED pathArr[1]")
}
}
}
}
我觉得我很接近,但缺少一些部分。我是否可能以错误的方式考虑递归或使其过于复杂?感谢帮助,谢谢!
编辑:
McLaren/BMW/Subaru/saab
表示新对象(KIA
)应该去哪里的路径。所以KIA
应该在名为 saab
的对象中放入 drivers
-arr 中。
递归Func() 检查路径名存在于哪个数组中,然后尝试使用此对象数组更深入地了解对象,以便找到路径的最后一部分(在本例中为 Saab)。新对象应推送到此数组。
这里有一个可以支持的想法:当数据难以处理时,转换您的数据。
我提出了一个可能更简单的替代解决方案:
创建一个对象,其中包含作为键的路径,以及对关联驱动程序数组的引用作为值。
var mapping = {};
function storeMap (chain, data) {
for (var i = 0; i < data.length; i++) {
var updatedChain = (chain && chain + '/') + data[i].name;
mapping[updatedChain] = data[i].drivers;
if (data[i].drivers.length) {
storeMap (updatedChain, data[i].drivers);
}
}
}
storeMap('', [data]);
然后,要添加您的项目,请执行以下操作:
var itemToAdd = { "name": "KIA", "drivers":[] };
var path = 'McLaren/BMW/Subaru/saab';
mapping[path].push(itemToAdd);
在可重用性的情况下,这本来是一次性的:你必须每次都运行地图存储,这不是很有效。您可以做的是使用在修改地图时更新地图的方法:
function addItem (item) {
mapping[path].push(item);
mapping[path + '/' + item.name] = item.drivers;
}
function removeItem (item) {
var parentPath = item.name.split('/').slice(0, -1).join('/');
var drivers = mapping[parentPath].drivers;
drivers.splice(drivers.indexOf(item), 1);
delete mapping[item.name];
}
您可以运行此代码{ drivers : [data] }
将根对象作为currentNode
传递。
var insert = function(currentNode, nodeToInsert, pathArr) {
if(pathArr.length == 0) {
currentNode.drivers.push(nodeToInsert);
return true;
}
for(var i = 0; i < currentNode.drivers.length; i++)
if(currentNode.drivers[i].name == pathArr[0])
return insert(currentNode.drivers[i], nodeToInsert, pathArr.splice(1));
return false;
}
请注意,在您的示例中,您在 JSON 中具有Saab
,在路径中saab
,这将导致路径搜索失败。
只是另一种解决方案,它将对象和路径作为数组。
function find(object, path) {
if (object.name.toLowerCase !== path.shift().toLowerCase) {
return;
}
return (!path.length || object.drivers.some(function (a) {
object = find(a, path.slice());
return object;
})) && object;
}
var data = { "name": "McLaren", "drivers": [{ "name": "BMW", "drivers": [{ "name": "VW", "drivers": [] }, { "name": "Subaru", "drivers": [{ "name": "Saab", "drivers": [{ "name": "Lexus", "drivers": [] }, { "name": "Honda", "drivers": [] }] }] }] }] },
path = 'McLaren/BMW/Subaru/Saab',
object = { "name": "KIA", "drivers": [] };
find(data, path.split('/')).drivers.push(object);
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
相关文章:
- 无递归的异步循环
- Javascript-用于展开数组的递归/for循环
- 循环内部的递归函数未按预期工作
- bluebird promise的while()循环正确(无递归?)
- for 循环/递归中的执行顺序
- 在递归循环javascript之后,为JSON键变量使用自定义HTML元素
- 通过递归循环同步ajax请求
- 对象数组中的递归循环
- 递归循环遍历数组并返回项数
- 为嵌套对象创建JS容器递归循环
- Javascript 递归循环到自动构建菜单结构不起作用
- javascript中的递归循环,基于链接单击的增量
- 什么'我的JavaScript搜索递归循环有问题
- 递归循环,直到我们'重新处理对象[JS]
- 如何在对象内部递归循环
- 将Javascript局部变量设置为全局变量以实现递归循环
- javascript在递归循环中返回未定义的数字
- 在递归循环中迭代和处理JSON对象会导致堆栈超出错误
- 为什么这些符号链接会发生无限递归循环
- Jquery绑定在javascript递归循环中不工作