Javascript : Modifier la valeur d'une "sous-clé"

En se basant sur un "chemin" dynamique

a marqué ce sujet comme résolu.

Bonjour,

Je rencontre une… Difficulté (C’est le cas de le dire :D ) dans le cadre d’un gros projet.

Pour situer le contexte, j’ai une fonction updateData() qui prend en paramètre un chemin et une valeur. Ce chemin peut être… Simple : "items". Dans ce cas, je peux faire directement :

this.datas[ path ] = value;

Y’a pas de problème là-dessus. "this.datas" est la variable contenant toutes mes keys, sub-keys avec leur valeur.

Maintenant, si dans updateData, je passe en premier paramètre "sub1.any.point.abg", je ne sais pas, et c’est pour ça que je me dirige vers vous, comment accéder à "this.datas[sub1][any][point][abg]", dynamiquement.

J’ai essayé en splittant sur les points et en faisant un eval() mais j’avais un "Unexpected identifier". Du coup, j’ai laissé tomber cette piste.

Pour l’instant, je suis sur cette piste :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
if(variable.match(/\./)){
    var keys_datas = variable.split(/[\.]/);
    var base_datas = this.datas;

    for(var i = 0; i < keys_datas.length; i++){
        base_datas = base_datas[ keys_datas[i] ];
    }
} else {
    this.datas[ variable ] = value;
}

Avec base_datas, j’accède bien à la dernière clé splittée provenant de this.datas, et je peux attribuer la valeur de cette façon, en dessous du for : base_datas = value;, maintenant, si je fais "this.datas = base_datas", je formate complètement this.datas pour ne lui attribuer que la valeur passée à updateData().

Comment je peux faire pour attribuer la value à la bonne clé dans this.datas sans supprimer les autres keys contenues ?

Je vous remercie.

Salut,

La meilleure façon de faire, c’est : https://lodash.com/docs/4.17.5#get

Sinon y’a moyen de programmer un truc similaire, oui. Ton code est très bizarre (au passage data est pluriel, datas n’a pas de sens).

  • Pourquoi .match(/\./) ? Si tu veux t’assurer qu’une chaine contient un ., utilise includes('.') (ou indexOf('.') !== -1).
  • Pourquoi .split(/[\.]/) ? Si tu veux splitter sur ., utilise .split('.').

A part ces remarques, je ne comprends pas pourquoi tu n’arrives pas à faire ce que tu veux faire ? Fais comme ça :

  1. cherche la valeur à modifier
  2. modifie-la
  3. fini :)
+0 -0

Salut,

La meilleure façon de faire, c’est : https://lodash.com/docs/4.17.5#get

Sinon y’a moyen de programmer un truc similaire, oui. Ton code est très bizarre (au passage data est pluriel, datas n’a pas de sens).

  • Pourquoi .match(/\./) ? Si tu veux t’assurer qu’une chaine contient un ., utilise includes('.') (ou indexOf('.') !== -1).
  • Pourquoi .split(/[\.]/) ? Si tu veux splitter sur ., utilise .split('.').

A part ces remarques, je ne comprends pas pourquoi tu n’arrives pas à faire ce que tu veux faire ? Fais comme ça :

  1. cherche la valeur à modifier
  2. modifie-la
  3. fini :)
victor

Dans le for, j’ai essayé tout simplement "this.datas = this.datas[ key ]", mais ça revient au même que faire "this.datas = base_data", ça supprime toutes les autres données contenues dans this.datas.

Je vais voir lodash, ça a l’air effectivement intéressant.

Ouais mais pourquoi tu vas pas simplement récupérer la bonne clé et modifier la valeur ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const x = {
  a: {
    b: {
      c: {
        x: 1
      },
      d: {
        y: 2,
        z: 3
      }
    }
  }
}

function foo(obj, path, val) {
  const parts = path.split('.').reverse()
  let objPart = obj
  while (parts.length > 1) {
    const pathPart = parts.pop()
    if (!objPart.hasOwnProperty(pathPart)) return
    objPart = objPart[pathPart]
  }
  objPart[parts.pop()] = val
}

foo(x, 'a.b.d.y', 77)
console.log(x['a']['b']['d']['y'] === 77)
+0 -0

Ouais mais pourquoi tu vas pas simplement récupérer la bonne clé et modifier la valeur ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const x = {
  a: {
    b: {
      c: {
        x: 1
      },
      d: {
        y: 2,
        z: 3
      }
    }
  }
}

function foo(obj, path, val) {
  const parts = path.split('.').reverse()
  let objPart = obj
  while (parts.length > 1) {
    const pathPart = parts.pop()
    if (!objPart.hasOwnProperty(pathPart)) return
    objPart = objPart[pathPart]
  }
  objPart[parts.pop()] = val
}

foo(x, 'a.b.d.y', 77)
console.log(x['a']['b']['d']['y'] === 77)
victor

Parce que je ne savais pas comment faire :-°

Mais ta fonction… Fonctionne. C’est effectivement plus complexe que je ne l’aurais imaginé :-° Merci :)

Plus complexe ? C’est extrêmement simple. Déroule ce que ça fait, c’est super bête.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const x = {
  a: {
    b: {
      c: {
        x: 1
      },
      d: {
        y: 2,
        z: 3
      }
    }
  }
}

path = 'a.b.d.y'
val = 77

parts = ['a', 'b', 'd', 'y']
// reverse ->
parts = ['y', 'd', 'b', 'a']
objPart = x = {
  a: {
    b: {
      c: {
        x: 1
      },
      d: {
        y: 2,
        z: 3
      }
    }
  }
}

pathPart = 'a'
objPart = objPart['a'] = {
  b: {
    c: {
      x: 1
    },
    d: {
      y: 2,
      z: 3
    }
  }
}

pathPart = 'b'
objPart = objPart['b'] = {
  c: {
    x: 1
  },
  d: {
    y: 2,
    z: 3
  }
}

pathPart = 'd'
objPart = objPart['d'] = {
  y: 2,
  z: 3
}

objPart['y'] = 77
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte