J'essaie de filtrer un JSON en JavaScript à tous les niveaux. Je veux conserver le "nom" de chacune des entrées à chaque niveau sur la base de si elle est présente dans un tableau. Si ce n'est pas présent à un certain niveau, continuez à travers les enfants.
noms acceptés: p> JSON original: p> var previous = ""
function loop(a) {
if (previous.name == a.name) {
previous = a
previous['true_children'] = []
}
if (accepted.includes(a.name)) {
previous['true_children'].push(a)
if (a.children != null) {
previous = a
previous['true_children'] = []
}
}
Array.isArray(a.children) && a.children.forEach(loop);
}
3 Réponses :
J'ai obtenu la sortie souhaitée avec la solution suivante, espérons que cela aide!
p>
const accepted = [ "top", "first", "three"];
const data = { "name": "top",
"children": [
{
"name": "first",
"children": [
{
"name": "second",
"children":[
{
"name": "three"
}
]
},
{
"name": "second",
"children":[
{
"name": "three"
}
]
},
{
"name": "second",
"children":[
{
"name": "three"
}
]
}
]
},
{
"name": "first",
"children": [
{
"name": "second",
"children":[
{
"name": "three"
}
]
},
{
"name": "second",
"children":[
{
"name": "three"
}
]
},
{
"name": "second",
"children":[
{
"name": "three"
}
]
}
]
}
]
}
function buildOutput(input, accepted) {
const filtered = Object.keys(input).reduce((accumulator, currentValue) => {
if(currentValue === 'name' && accepted.find(x => input[currentValue] === x)) {
accumulator[currentValue] = input[currentValue];
if(input['children']){
accumulator['children'] = input['children'].map(x => buildOutput(x, accepted)).filter(x => x);
if(!accumulator['children'].length){
accumulator['children'] = flattenChildren(input['children']).map(x => buildOutput(x, accepted)).filter(x => x);
}
}
}
return accumulator;
}, {});
return Object.keys(filtered).length ? filtered : null;
}
function flattenChildren(children) {
return children.reduce((accumulator, currentValue) => accumulator.concat(currentValue.children), []);
}
console.log(buildOutput(data, accepted));Voici une autre solution récursive, j'espère ne pas difficile à comprendre.
p>
var accepted = ["top", "first", "three"],
data = {"name": "top", "children": [{"name": "first", "children": [{"name": "second", "children": [{"name": "three"}]}, {"name": "second", "children": [{"name": "three"}]}, {"name": "second", "children": [{"name": "three"}]}]}, {"name": "first", "children": [{"name": "second", "children": [{"name": "three"}]}, {"name": "second", "children": [{"name": "three"}]}, {"name": "second", "children": [{"name": "three"}]}]}]};
function transform(accepted, data) {
const children = data.children || [],
result = { name: data.name, children: [] },
isAccepted = accepted.includes(data.name);
children.forEach(child => {
child = transform(accepted, child);
const children = Array.isArray(child) ? child : [child];
result.children.push(...children);
});
// Guard against data that isn't accepted.
if (!isAccepted) return result.children;
// Delete the children key if the array is empty.
if (!children.length) delete result.children;
return result;
}
console.log(transform(accepted, data));Pour la chaîne JSON, le filtrage peut être effectué lors de l'analyse:
p>
var accepted = ["top", "first", "three"], json = '{"name":"top","children":[{"name":"first","children":[{"name":"second","children":[{"name":"three"}]},{"name":"second","children":[{"name":"three"}]},{"name":"second","children":[{"name":"three"}]}]},{"name":"first","children":[{"name":"second","children":[{"name":"three"}]},{"name":"second","children":[{"name":"three"}]},{"name":"second","children":[{"name":"three"}]}]}]}'
var obj = JSON.parse(json, (k, v) => k == 'name' && !accepted.includes(v) ? void 0 :
v.children && v.children.length === 1 && !v.name ? v.children[0] : v)
console.log( obj )
Pouvez-vous mettre à jour votre question pour fournir des éclaircissements sur 1) Quelle est la réponse attendue lorsque
accepté = ["premier", "trois"] code>? Et 2) Quelle est la réponse attendue lorsqueaccepté = [] code>?