2017-08-15 114 views
0

我需要通过对象列表来查找元素并向根添加新元素,我可以滚动列表并找到元素,但无法将其添加到正确的级别为对象添加元素

var data = [ 

    { 
     "id": 1 
    }, 
    { 
     "id": 2 
    }, 
    { 
     "id": 3 
    }, 
    { 
     "id": 4, 
     "children": [ 
      { 
       "id": 6 
      }, 
      { 
       "id": 7      
      } 
     ] 
    }, 
    { 
     "id": 5 
    } 

]; 

function findById(data, id, element) { 
    function iter(a) { 
     if (a.id === id) { 
      a.push(element); // ERROR 
      result = a; 
      return true; 
     } 
     return Array.isArray(a.children) && a.children.some(iter); 
    } 
    var result; 
    data.some(iter); 
    return result 
} 


var element = { 
    "children": [{"id": 6}] 
}; 

findById(data, 5, element); 

document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>'); 

https://jsfiddle.net/4nrsccnu/

+1

a.push不做任何事情,因为它不是数组。尝试推入阵列。 –

+1

'a.push'抛出错误,因为'a'是不包含数组的对象。您需要使用'Array.indexOf'在'data'中获取'a'的位置。然后参考:https://stackoverflow.com/questions/586182/how-to-insert-an-item-into-an-array-at-a-specific-index –

+0

你可能试图做到这一点,虽然:' a.children.push'而不是'a.push'这会在你的示例中使id为5的对象具有id为6的元素的子元素。 –

回答

1

你不能push,因为a是一个对象。但是,您可以简单地添加所需的属性(在您的案例中,children),然后为其分配一个值(在您的情况下,为element)。

var data = [ 
 

 
    { 
 
     "id": 1 
 
    }, 
 
    { 
 
     "id": 2 
 
    }, 
 
    { 
 
     "id": 3 
 
    }, 
 
    { 
 
     "id": 4, 
 
     "children": [ 
 
      { 
 
       "id": 6 
 
      }, 
 
      { 
 
       "id": 7      
 
      } 
 
     ] 
 
    }, 
 
    { 
 
     "id": 5 
 
    } 
 

 
]; 
 

 
function findById(data, id, element) { 
 
    function iter(a) { 
 
     if (a.id === id) { 
 
      a.children = element; // Add property 'children' 
 
      result = a; 
 
      return true; 
 
     } 
 
     return Array.isArray(a.children) && a.children.some(iter); 
 
    } 
 
    var result; 
 
    data.some(iter); 
 
    return result 
 
} 
 

 
// remove property name from element, as that is being added in the function 
 
var element = [ 
 
    {"id": 6} 
 
]; 
 

 
findById(data, 5, element); 
 

 
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');

1

使用Object.assignelement对象的属性合并到迭代的当前对象。

var data = [ 
 

 
    { 
 
     "id": 1 
 
    }, 
 
    { 
 
     "id": 2 
 
    }, 
 
    { 
 
     "id": 3 
 
    }, 
 
    { 
 
     "id": 4, 
 
     "children": [ 
 
      { 
 
       "id": 6 
 
      }, 
 
      { 
 
       "id": 7      
 
      } 
 
     ] 
 
    }, 
 
    { 
 
     "id": 5 
 
    } 
 

 
]; 
 

 
function findById(data, id, element) { 
 
    function iter(a) { 
 
     if (a.id === id) { 
 
      Object.assign(a, element); 
 
      result = a; 
 
      return true; 
 
     } 
 
     return Array.isArray(a.children) && a.children.some(iter); 
 
    } 
 
    var result; 
 
    data.some(iter); 
 
    return result 
 
} 
 

 

 
var element = { 
 
    "children": [{"id": 6}] 
 
}; 
 

 
findById(data, 5, element); 
 

 
console.log(data);

+0

我需要一个能够挂载对象树的结构,我通过这种方式可以传递父ID和要插入的元素,请您评估一下这是否是最好的方法。 https://jsfiddle.net/5ajxhwx3/2/ –

+1

这似乎很好。该函数的'element'参数与您在问题中显示的内容不同。这意味着该函数只能添加子项,而不能添加其他属性,但它可以将其他子项添加到已有子项的节点。 – Barmar

+0

是的,并为此添加孩子和兄弟元素 –

1

push功能用于arrays,不反对。检查详细信息https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

如果要将单个密钥对添加到对象中,可以使用Object.keysObject.values。像这样:

function findById(data, id, element) { 
    function iter(a) { 
     if (a.id === id) { 
      var key = Object.keys(element)[0]; 
      var value = Object.values(element)[0]; 
      a[key] = value; 
      result = a; 
      return true; 
     } 
     return Array.isArray(a.children) && a.children.some(iter); 
    } 

    var result; 
    data.some(iter); 
    return result; 
}