我有一个这样的数组:
[
{"id":"one","name":"school", "selected": false, "children":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "children":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "children":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
]
如何过滤该数组以仅获取将字段选为true的对象的名称?
输出应该是对象名称的数组:
[student, school, school]
我用lodash尝试了这个:
_.filter(array, {selected: true}).map(function (division) {
return array.name;
});
但是这总是返回根对象,而不是子对象内的对象。
答案 0 :(得分:3)
您可以迭代并查看所需属性selected
是否为true
,如果有子项则推送到结果,迭代子项。
这适用于Array#forEach
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = [];
data.forEach(function iter(o) {
o.selected && result.push(o.name);
(o.children || []).forEach(iter);
});
console.log(result);
与lodash _.forEach
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = [];
_.forEach(data, function iter(o) {
o.selected && result.push(o.name);
_.forEach(o.children, iter);
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Array#reduce
的版本。
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = data.reduce(function iter(r, o) {
o.selected && r.push(o.name);
return (o.children || []).reduce(iter, r);
}, []);
console.log(result);
另一个版本是lodash _.reduce
。
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = _.reduce(data, function iter(r, o) {
o.selected && r.push(o.name);
return _.reduce(o.children, iter, r);
}, []);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
答案 1 :(得分:1)
array
.reduce((a, i) => [...a, i, ...i.childs], [])//flatten array
.filter(i => i.selected)//filter with selected===true
.map(i => i.name));//map to name
console.log([{
"id": "one",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "two",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "three",
"name": "school",
"selected": true,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": false
}]
}].reduce((a, i) => [...a, i, ...i.childs], []).filter(i => i.selected).map(i => i.name));
答案 2 :(得分:1)
您可以使用此函数式编程样式的ES6解决方案:
function sel(array) {
return (array || []).reduce ( (acc, o) =>
(o.selected ? acc.concat(o.name) : acc).concat(sel(o.childs)), [] );
}
function sel(array) {
return (array || []).reduce ( (acc, o) =>
(o.selected ? acc.concat(o.name) : acc).concat(sel(o.childs)), [] );
}
// Sample data
var array = [
{"id":"one","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
];
// Extract
var result = sel(array);
// Ooutput result
console.log(result);
&#13;
答案 3 :(得分:1)
您可以使用Array.prototype.map()
,Array.prototype.filter()
var arr = [{
"id": "one",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "two",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "three",
"name": "school",
"selected": true,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": false
}]
}];
var res = arr.map(el =>
(el.selected && el || el.childs.filter(child =>
child.selected
)[0]).name
);
console.log(res);
&#13;
答案 4 :(得分:0)
那么,您应该考虑您尝试构建的脚本的复杂性。这是一个嵌套的线性算法(参见https://en.wikipedia.org/wiki/Linear_search),因为您必须触摸数组中的每个元素以创建具有selected
元素的新数据结构,如果该数组大小增加,这可能会非常慢
您可能想要做的是修改切换selected
属性的方法,并将该“选定”对象复制到新的selectedElements
数组。
但是,如果您需要按照自己的要求进行操作,并且只需要独特的结果,请查看以下内容:
var data = [
{"id":"one","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
],
selectedElements = [];
data.map(function(row, i){
if (row.selected) {
if (selectedElements.indexOf(row.name) == - 1)
selectedElements.push(row.name);
}
else{
row.childs.map(function(childRow, ii) {
if (childRow.selected) {
if (selectedElements.indexOf(childRow.name) == - 1)
selectedElements.push(childRow.name);
}
})
}
});
console.log(selectedElements);
答案 5 :(得分:0)
在你的lodash _.filter
之前添加一行array = _.flatten(array.map(x => [x].concat(x.childs)))
所以需要childs
。
答案 6 :(得分:0)
带箭头功能的经典递归解决方案
var result = [];
var recursiveSearch = arr => {
if (Array.isArray(arr)) {
arr.forEach(x => {
if (x.selected === true) result.push(x.name);
if (Array.isArray(x.childs)) recursiveSearch(x.childs);
});
}
}
recursiveSearch(data);
console.log (result);