我有一个对象数组,我需要向该对象以及具有相同值的父数组/对象添加一个键。
以下是我的实现:
const data = [{
"label": "Grand Parent 1",
"index": 0,
"code": "GRAND_PARENT_1",
"defaultCollapsed": true,
"items": [{
"id": 1,
"items": [{
"id": 100,
"label": "Child 1",
"url": "#CHILD_1",
"code": "CHILD_1"
},
{
"id": 200,
"label": "Child 2",
"url": "#CHILD_2",
"code": "CHILD_2"
},
{
"id": 300,
"label": "Child 3",
"url": "#CHILD_3",
"code": "CHILD_3"
},
{
"id": 400,
"label": "Child 4",
"url": "#CHILD_4",
"code": "CHILD_4"
}
],
"defaultCollapsed": false,
"label": "Parent 1"
},
{
"id": 2,
"items": [],
"defaultCollapsed": true,
"label": "Parent 2"
},
{
"id": 3,
"items": [],
"defaultCollapsed": true,
"label": "Parent 3"
},
{
"id": 4,
"items": [],
"defaultCollapsed": true,
"label": "Parent 4"
}
]
},
{
"label": "Grand Parent 2",
"index": 1,
"code": "GRAND_PARENT_2",
"defaultCollapsed": true,
"items": []
},
{
"label": "Grand Parent 3",
"index": 2,
"code": "GRAND_PARENT_3",
"defaultCollapsed": true,
"items": []
}
]
const filterData = (data, value) => {
const r = _.filter(data, item => {
const dataMap = _.map(item.items, subItem => {
const subItemMap = _.map(subItem.items, subsecItem => {
if(subsecItem.code === value) {
return item
}
})
})
})
return r;
}
console.log(filterData(data, 'CHILD_1'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
因此,当函数的值为CHILD_1时,我想向子级和父级对象添加名为selected: true
的键;
预期输出:
[
{
"label": "Grand Parent 1",
"index": 0,
"code": "GRAND_PARENT_1",
"defaultCollapsed": true,
"selected": true,
"items": [
{
"id": 1,
"items": [
{
"id": 100,
"label": "Child 1",
"url": "#CHILD_1",
"code": "CHILD_1",
"selected": true
},
{
"id": 200,
"label": "Child 2",
"url": "#CHILD_2",
"code": "CHILD_2"
},
{
"id": 300,
"label": "Child 3",
"url": "#CHILD_3",
"code": "CHILD_3"
},
{
"id": 400,
"label": "Child 4",
"url": "#CHILD_4",
"code": "CHILD_4"
}
],
"defaultCollapsed": false,
"label": "Parent 1",
"selected": true
},
{
"id": 2,
"items": [],
"defaultCollapsed": true,
"label": "Parent 2"
},
{
"id": 3,
"items": [],
"defaultCollapsed": true,
"label": "Parent 3"
},
{
"id": 4,
"items": [],
"defaultCollapsed": true,
"label": "Parent 4"
}
]
},
{
"label": "Grand Parent 2",
"index": 1,
"code": "GRAND_PARENT_2",
"defaultCollapsed": true,
"items": []
},
{
"label": "Grand Parent 3",
"index": 2,
"code": "GRAND_PARENT_3",
"defaultCollapsed": true,
"items": []
}
]
请咨询。我被困在尝试根据值过滤数据。
答案 0 :(得分:1)
此解决方案效率更高,因为一旦找到给定的孩子,它将立即停止。 forEach()
不允许您这样做。我还发现阅读起来更加清晰。
function select(items, value) {
if (!Array.isArray(items)) {
return false;
}
for (const item of items) {
if (item.code === value || select(item.items, key, value)) {
item.selected = true;
return true;
}
}
return false;
}
select(data, "CHILD_1");
select()
如果找到孩子,则返回true,否则返回false。
如果您需要取消选择先前选择的内容:
function reset(items) {
if (!Array.isArray(items)) {
return;
}
for (const item of items) {
if (item.selected) {
reset(item.items);
delete item.selected;
break;
}
}
}
reset(data);
这种方法与选择一样聪明,因为一旦找到所选元素,它就会停止。
要同时执行这两项:
function resetAndSelect(data, value) {
reset(data);
select(data, value);
}
答案 1 :(得分:0)
您可以采用返回true
或false
的函数,具体取决于要使用其他属性更新对象的所需键/值。
这种方法适用于任意深度的数据。
function update(array, key, value, object) {
var found = false;
array.forEach(o => {
if (o[key] === value || update(o.items || [], key, value, object)) {
found = true;
Object.assign(o, object);
}
});
return found;
}
var data = [{ label: "Grand Parent 1", index: 0, code: "GRAND_PARENT_1", defaultCollapsed: true, items: [{ id: 1, items: [{ id: 100, label: "Child 1", url: "#CHILD_1", code: "CHILD_1" }, { id: 200, label: "Child 2", url: "#CHILD_2", code: "CHILD_2" }, { id: 300, label: "Child 3", url: "#CHILD_3", code: "CHILD_3" }, { id: 400, label: "Child 4", url: "#CHILD_4", code: "CHILD_4" }], defaultCollapsed: false, label: "Parent 1" }, { id: 2, items: [], defaultCollapsed: true, label: "Parent 2" }, { id: 3, items: [], defaultCollapsed: true, label: "Parent 3" }, { id: 4, items: [], defaultCollapsed: true, label: "Parent 4" }] }, { label: "Grand Parent 2", index: 1, code: "GRAND_PARENT_2", defaultCollapsed: true, items: [] }, { label: "Grand Parent 3", index: 2, code: "GRAND_PARENT_3", defaultCollapsed: true, items: [] }];
update(data, 'code', 'CHILD_1', { selected: true });
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果您希望将所有未找到的项目设置为false
,则可以采用深度优先的方法来访问所有元素。
function update(array, value) {
var found = false;
array.forEach(o => {
o.selected = update(o.items || [], value) || o.code === value;
found = found || o.selected;
});
return found;
}
var data = [{ label: "Grand Parent 1", index: 0, code: "GRAND_PARENT_1", defaultCollapsed: true, items: [{ id: 1, items: [{ id: 100, label: "Child 1", url: "#CHILD_1", code: "CHILD_1" }, { id: 200, label: "Child 2", url: "#CHILD_2", code: "CHILD_2" }, { id: 300, label: "Child 3", url: "#CHILD_3", code: "CHILD_3" }, { id: 400, label: "Child 4", url: "#CHILD_4", code: "CHILD_4" }], defaultCollapsed: false, label: "Parent 1" }, { id: 2, items: [], defaultCollapsed: true, label: "Parent 2" }, { id: 3, items: [], defaultCollapsed: true, label: "Parent 3" }, { id: 4, items: [], defaultCollapsed: true, label: "Parent 4" }] }, { label: "Grand Parent 2", index: 1, code: "GRAND_PARENT_2", defaultCollapsed: true, items: [] }, { label: "Grand Parent 3", index: 2, code: "GRAND_PARENT_3", defaultCollapsed: true, items: [] }];
update(data, 'CHILD_1');
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }