私はこの配列を持っています:
[
{
id: 1,
name: 'test 1',
children: []
},
{
id: 2,
name: 'test 2',
children: [
{
id: 4,
name: 'test 4'
}
]
},
{
id: 3,
name: 'test 3',
children: []
}
]
この配列およびネストされたid
配列の両方でchildren
プロパティでフィルタリングするにはどうすればよいですか?
たとえば、id = 3
を検索するとtest 3
オブジェクトが返され、id = 4
を検索するとtest 4
オブジェクトが返されます。
これは非常に単純な tree traversal タスクです。これを解決する最も簡単な方法は再帰です( jsbin へのリンク)。それはどんな深さでも動作します(もちろん再帰の制限があります)。これは最悪の複雑さO(n)を持つ最速の方法の1つです。
function find(id, items) {
var i = 0, found;
for (; i < items.length; i++) {
if (items[i].id === id) {
return items[i];
} else if (_.isArray(items[i].children)) {
found = find(id, items[i].children);
if (found) {
return found;
}
}
}
}
すべての一致を見つける-わずかに変更された関数(上記のjsbinリンクが更新されます):
function findAll(id, items) {
var i = 0, found, result = [];
for (; i < items.length; i++) {
if (items[i].id === id) {
result.Push(items[i]);
} else if (_.isArray(items[i].children)) {
found = findAll(id, items[i].children);
if (found.length) {
result = result.concat(found);
}
}
}
return result;
}
子キーと無制限の深さを持つ別のlodash
オプション。
const flattenItems = (items, key) => {
return items.reduce((flattenedItems, item) => {
flattenedItems.Push(item)
if (Array.isArray(item[key])) {
flattenedItems = flattenedItems.concat(flattenItems(item[key], key))
}
return flattenedItems
}, [])
}
const item = find(flattenItems(items, 'children'), ['id', 4])