TypeScript : pousser vers un tableau d'objets JSON imbriqués

J'essaie d'ajouter et de supprimer des valeurs d'un tableau d'objets json NESTED. La suppression était facile mais j'ai du mal avec l'ajout:

export const addNestedJson = (
json: Record<string, any> | any[],
value: any,
keys: string[]
): Record<string, any> | any[] => {
// Please pass in mutated Values before calling the function
const isJSONArray = Array.isArray(json);
if (keys.length === 0) {
if (isJSONArray) {
return [...json, value];
}
return json;
}
const key = keys.shift() as string;
const index = key?? 0;
const indexKey = isNaN(+index)? 0: +index;
const newJson = isJSONArray? json[indexKey]: json[key];
const nestedJsonValue = addNestedJson(newJson, value, keys);
return isJSONArray
? [...json, nestedJsonValue]
: {...json, [key]: nestedJsonValue };
}

J'essaie d'utiliser la récursivité car cela semble être la solution la plus simple, mais pour une raison quelconque, je ne suis pas en mesure de visualiser et de formuler la logique de fusion.

Voici ce que j'attends :

JSON: [], key: [], valueTobeAdded: 1 should return [1]

JSON: [{a: {b:[]}}], key: ['a','b'], valueTobeAdded: 1 should return [{a:{b:[1]}}]

JSON: [{a: {b:[{c:[4]}]}}], key: ['a','b','0','c'], valueTobeAdded: 1 should return [{a: {b:[{c:[4,1]}]}}]


Solution du problème

Tout d'abord, je pense que les deux derniers exemples de sortie attendue ne définissent pas un fichier key. Étant donné que les entrées sont des tableaux à leur niveau supérieur et que vous vous attendez à ce que la première valeur du tableau soit remplacée, vous devez avoir 0 comme première entrée dans le fichier key.

Dans le code, je vois deux problèmes et j'ai quelques remarques supplémentaires :

  • Dans le cas où keysle tableau est vide et que les données ne sont pas un tableau, elles doivent être remplacées par la nouvelle valeur, donc au lieu de return json, vous devezreturn value


  • Lorsque vous revenez de l'appel récursif et que le niveau actuel est un tableau, la nouvelle valeur ne doit pas être ajoutée au tableau, mais plutôt être la valeur de remplacement pour ce qui était à indexKey.


  • Pas un vrai problème, mais je ne muterais pas keys.


  • Pas de problème avec l'algorithme, mais le nom jsondans vos noms de propriété et de variable n'est pas approprié. JSON est quelque chose que vous devez transmettre JSON.parse. Tout le reste ne doit pas être appelé JSON.


  • Cela se traduit par le code adapté suivant :

    const addNested = (
    data: Record<string, any> | any[],
    value: any,
    keys: string[]
    ): Record<string, any> | any[] => {
    const isArray = Array.isArray(data);
    if (keys.length === 0) {
    if (isArray) {
    return [...data, value];
    }
    return value; // Overwrite any data
    }
    // Don't mutate keys with shift
    const key = keys[0] as string;
    const indexKey = +key || 0;
    const newData = isArray? data[indexKey]: data[key];
    const nestedValue = addNested(newData, value, keys.slice(1));
    return isArray
    ? Object.assign([], data, { [indexKey]: nestedValue }) // Replace at index
    : {...data, [key]: nestedValue };
    }


    const addNested = (
    data /*: Record<string, any> | any[] */,
    value /*: any */,
    keys /*: string[] */
    ) /*: Record<string, any> | any[] */ => {
    const isArray = Array.isArray(data);
    if (keys.length === 0) {
    if (isArray) {
    return [...data, value];
    }
    return value; // Overwrite any data
    }
    // Don't mutate keys with shift
    const key = keys[0] /* as string */;
    const indexKey = +key || 0;
    const newData = isArray? data[indexKey]: data[key];
    const nestedValue = addNested(newData, value, keys.slice(1));
    return isArray
    ? Object.assign([], data, { [indexKey]: nestedValue }) // Replace at index
    : {...data, [key]: nestedValue };
    }
    console.log(addNested([], 1, [])); // [1]
    console.log(addNested([{a: {b:[]}}], 1, [0,'a','b'])); // [{a:{b:[1]}}]
    console.log(addNested([{a: {b:[{c:[4]}]}}], 1, [0,'a','b','0','c'])); // [{a: {b:[{c:[4,1]}]}}]

    Commentaires

    Posts les plus consultés de ce blog

    Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

    Détecter les appuis sur les touches fléchées en JavaScript

    Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"