深くネストされたオブジェクトの配列があります。これらの配列から任意の子オブジェクトを抽出する関数を書きたいと思います。ネストされたプロパティの値が値とオブジェクトである場合もあれば、配列である場合もあります。
配列の例を以下に示します。
[{parent: {level1: {level2: 'data'}}}]
[{parent: {level1: [{level2: {...}}, {level2: {...}}, {level2: {...}}]}}]
[{parent: {level1: [{level2: {level3: 'data'}}, {level2: {..}}, {level2: {..}}]}}]
このような配列で抽出関数を呼び出すと、関心のあるオブジェクトの配列が生成されます。
上記の配列例の関数とその結果の呼び出し例:
extractChildren(source, 'level2') = [{level2: 'data'}]
extractChildren(source, 'level2') = [{level2: {...}, level2: {...}, level2: {...}]
extractChildren(source, 'level3') = [{level3: 'data'}]
lodash
を使用してこれを実現する簡潔な方法はありますか、それとも通常のJavaScriptを使用してプロパティを反復処理する必要がありますか?
P.S. XPath select all nodes with the name "nodename"
と同等のものと考えてください
から この質問 :
エレガント:
function find_obj_by_name(obj, key) {
if( !(obj instanceof Array) ) return [];
if (key in obj)
return [obj[key]];
return _.flatten(_.map(obj, function(v) {
return typeof v == "object" ? find_obj_by_name(v, key) : [];
}), true);
}
効率的:
function find_obj_by_name(obj, key) {
if( !(obj instanceof Array) ) return [];
if (key in obj)
return [obj[key]];
var res = [];
_.forEach(obj, function(v) {
if (typeof v == "object" && (v = find_obj_by_name(v, key)).length)
res.Push.apply(res, v);
});
return res;
}
私はそれが役立つことを願っています:
'use strict';
let _ = require("lodash");
let source = [{parent: {level1: [{level2: {level3: 'data'}}, {level2: {}}, {level2: {}}]}}];
function extractChildren(source, specKey) {
let results = [];
let search = function(source, specKey) {
_.forEach(source, function(item) {
if (!!item[specKey]) {
let obj = {};
obj[specKey] = item[specKey];
results.Push(obj);
return;
}
search(item, specKey);
});
};
search(source, specKey);
return results;
};
console.log(extractChildren(source, 'level3'));
// [ { level3: 'data' } ]