0
votes

Niveaux de filtrage de JSON en JavaScript à maintenir de manière récursive les enfants

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> xxx pré>

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); 
}


1 commentaires

Pouvez-vous mettre à jour votre question pour fournir des éclaircissements sur 1) Quelle est la réponse attendue lorsque accepté = ["premier", "trois"] ? Et 2) Quelle est la réponse attendue lorsque accepté = [] ?


3 Réponses :


0
votes

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));


0 commentaires

0
votes

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));


0 commentaires

1
votes

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 )


0 commentaires