我在使用lodash的nodejs应用程序中有一个树数据结构:
var l = require("lodash");
obj_string =
`
[
{
"father_id": 1,
"name": "father 1",
"child_array": [
{
"id": 11,
"name": "father 1 child 1"
},
{
"id": 12,
"name": "father 1 child 2"
}
]
},
{
"father_id": 2,
"name": "father 2",
"child_array": [
{
"child_id": 21,
"name": "father 2 child 1"
},
{
"child_id": 22,
"name": "father 2 child 2 - TO DELETE"
}
]
}
]
`;
tree = JSON.parse(obj_string);
我想通过ID删除一个孩子,但我不知道他的父亲是什么
l.chain(tree).flatMap(f=>f.child_array).remove(c=>c.child_id==22);
它不起作用,为什么!?我用过Java流,但不了解lodash是如何工作的。 例如,如果我要搜索一个孩子,并且想要引用已建立的孩子,例如为了编辑其成员(没有_.map),该怎么办?
与此:
ret = l.chain(tree).flatMap(f=>f.child_array).find(c=>c.child_id==22).value();
我在ret中有一个新对象,因此我无法访问/编辑原始对象。 换句话说,第二个问题是:如何从lodash包装器检索对象引用?
答案 0 :(得分:0)
您可以遍历数组并拒绝child_array
中不需要的项目。请注意,这将修改原始对象。
const obj = [{"father_id":1,"name":"father 1","child_array":[{"id":11,"name":"father 1 child 1"},{"id":12,"name":"father 1 child 2"}]},{"father_id":2,"name":"father 2","child_array":[{"child_id":21,"name":"father 2 child 1"},{"child_id":22,"name":"father 2 child 2 - TO DELETE"}]}];
_.forEach(obj, item => {
item.child_array = _.reject(item.child_array, {child_id: 22});
});
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
答案 1 :(得分:0)
恕我直言,您还可以使用Vanilla ES6
来实现类似的输出,如下所示:
var arr =[{"father_id":1,"name":"father 1","child_array":[{"id":11,"name":"father 1 child 1"},{"id":12,"name":"father 1 child 2"}]},{"father_id":2,"name":"father 2","child_array":[{"child_id":21,"name":"father 2 child 1"},{"child_id":22,"name":"father 2 child 2 - TO DELETE"}]}];
var newArr = arr.map(obj => {
return obj.child_array[0].child_id ?
(obj.child_array = obj.child_array.filter(c => c.child_id != 22), obj)
: obj;
});
console.log(newArr);
答案 2 :(得分:0)
我认为重要的是要认识到lodash
的工作原理完全符合您的示例。问题是您做了flatMap(f=>f.child_array)
,它告诉lodash接受child_array
并将其返回到下一个链式操作。接下来,它按预期方式进行操作,删除了与ID匹配的子项,现在剩下的是您通过flatMap
的返回请求的子项集合。
似乎您真正想要的是通过fathers
映射,删除与ID匹配的子项,然后返回the father
。
例如,这样做:
var data = [{"father_id":1,"name":"father 1","child_array":[{"id":11,"name":"father 1 child 1"},{"id":12,"name":"father 1 child 2"}]},{"father_id":2,"name":"father 2","child_array":[{"child_id":21,"name":"father 2 child 1"},{"child_id":22,"name":"father 2 child 2 - TO DELETE"}]}];
removeById = (id, data) => _.map(data, father => {
father.child_array = _.reject(father.child_array, { child_id: id })
return father
})
console.log(removeById(22, data)) // 2 fathers with 2nd child removed from 2nd father
console.log(removeById(11, data)) // 2 fathers with 1 child each now
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
答案 3 :(得分:0)
这是使用object-scan的另一个答案。一旦将数据包住头,它对于处理数据斑点非常强大。
这将修改原始对象。
const objectScan = require('object-scan');
const prune = (id, input) => objectScan(['**'], {
abort: true, // abort after first match
rtn: 'bool',
filterFn: ({ value, parent, property }) => {
if (value.child_id === id) {
parent.splice(property, 1);
return true;
}
return false;
}
})(input);
const obj = [{"father_id":1,"name":"father 1","child_array":[{"id":11,"name":"father 1 child 1"},{"id":12,"name":"father 1 child 2"}]},{"father_id":2,"name":"father 2","child_array":[{"child_id":21,"name":"father 2 child 1"},{"child_id":22,"name":"father 2 child 2 - TO DELETE"}]}];
console.log(prune(22, obj)); // returns true iff replacement made
// => true
console.log(JSON.stringify(obj));
// => [{"father_id":1,"name":"father 1","child_array":[{"id":11,"name":"father 1 child 1"},{"id":12,"name":"father 1 child 2"}]},{"father_id":2,"name":"father 2","child_array":[{"child_id":21,"name":"father 2 child 1"}]}]