[英]filter array recursively looking for parents
我有一個像這樣的數組:
[
{"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;
});
但這總是返回根對象,而不是子對象內部的對象。
您可以僅迭代並查看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>
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));
您可以使用以下功能編程風格的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);
您可以使用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);
好吧,您應該考慮要構建的腳本的復雜性。 這是一個嵌套的線性算法(請參閱https://en.wikipedia.org/wiki/Linear_search ),因為您必須觸摸數組中的每個元素以使用selected
元素創建新的數據結構,如果selected
,這可能會很慢數組大小增加。
您可能想要做的是,修改切換selected
屬性的方法,然后將“選定”對象復制到新的selectedElements
數組中。
但是,如果您需要按照自己的要求做,而只想要UNIQUE結果,請檢查以下內容:
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);
在lodash _.filter之前添加一行
array = _.flatten(array.map(x => [x].concat(x.childs)))
這樣就需要childs
。
具有箭頭功能的經典遞歸解決方案
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.