Je voudrais transformer un objet basé sur une chaîne de notation de points dans un autre objet. Par exemple:
const objToTransform = {
"a": "aValue",
"b": {
"c": "cValue",
"d": "dValue"
}
};
const filteringObj = {
"field1": "a",
"field2": {
"subfield1": "b.c",
"subfield2": "b.d"
}
};
const filteredObj = myFunc(objToTransform, filteringObj);
// expect outputs to be:
// {
// "field1": "aValue",
// "field2": {
// "subfield1": "cValue",
// "subfield2": "dValue"
// }
// }
5 Réponses :
Vous pouvez le faire en suivant les étapes suivantes à l'aide de la récursivité:
filtrantObj code>. li>
- Créer une fonction d'assistance
getbypeath code> qui prend des objets et du chemin et de la valeur de retour sur ce chemin de l'objet imbriqué li>
- Créer une fonction
transformer code> qui boucle sur les touches de filtrantObj code> (je l'ai nommé motif code> dans la fonction) li>
- dans la face de la boucle Vérifiez si la valeur est un objet, appelez ensuite la fonction
transformer code> de manière récursive sur cette subuvect li>
- Si ce n'est pas un objet, obtenez la valeur de l'objet d'origine
ObjectTotransform code> à l'aide de GetByPath code> Fonction Li>
ul> p>
const objToTransform = {
"a": "aValue",
"b": {
"c": "cValue",
"d": "dValue"
}
};
const filteringObj = {
"field1": "a",
"field2": {
"subfield1": "b.c",
"subfield2": "b.d"
}
};
function getByPath(obj, path){
//console.log(path)
return path.split('.').reduce((ac,a) => ac[a], obj);
}
function transform(obj, pattern){
for(let key in pattern){
if(typeof pattern[key] === "object"){
transform(obj, pattern[key]);
}
else{
pattern[key] = getByPath(obj, pattern[key]);
}
}
}
const copy = JSON.parse(JSON.stringify(filteringObj))
transform(objToTransform, copy);
console.log(copy) Vous pouvez créer une fonction récursive à l'aide de code> Réduire la méthode code> qui créera une appel récursive à chaque fois que la valeur est de type objet de type.
p>
const objToTransform = {
"a": "aValue",
"b": {
"c": "cValue",
"d": "dValue"
}
};
const filteringObj = {
"field1": "a",
"field2": {
"subfield1": "b.c",
"subfield2": "b.d"
}
};
function transform(a, b) {
return Object.entries(b).reduce((r, [k, v]) => {
r[k] = typeof v !== 'object' ?
v.split('.').reduce((r, e) => r[e], a) :
transform(a, v)
return r;
}, {})
}
const result = transform(objToTransform, filteringObj)
console.log(result)J'ai fait une algue récursive:
p>
const getRefVal=(ePath, eData)=>ePath.split('.').reduce((r,x)=>r[x], eData);
function myFunc(oData, oModel) {
let ret = {};
setKeyVal(oModel,ret);
function setKeyVal(src,res) { // recursive function
for (let [k,v] of Object.entries(src)) {
if (typeof src[k]==='object') { res[k] = {}; setKeyVal(v,res[k]) }
else { res[k] = getRefVal(v,oData) }
}
}
return ret
}
const objToTransform= { a: 'aValue', b: { c: 'cValue', d: 'dValue' } }
, filteringObj = { field1: 'a', field2: { subfield1: 'b.c', subfield2: 'b.d' } };
// test
const filteredObj = myFunc(objToTransform, filteringObj);
// proof
console.log( filteredObj ) Lodash vous permet d'utiliser très facilement la notation du point.
Voici exactement ce que vous voulez (<10 lignes):
Si vous utilisez (ou souhaitée utiliser) Ramda (non-responsabilité: Je suis un si ses auteurs primaires ), cela pourrait fonctionner pour vous. Ramda n'a pas de fonction code> deepmap code>, mais il est facile d'en écrire un. Et en utilisant cela, votre fonction de transformation est une doublure:
p>
const transform = (objToTransform, filteringObj) =>
applySpec(deepMap (compose (path, split('.'))) (filteringObj)) (objToTransform)
S'il vous plaît montrer jusqu'où tu as eu; Vous pourriez être un peu un peu hors tension et il serait dommage de gaspiller le temps des gens quand il pourrait prendre 5 minutes, n'est-ce pas?
Je viens d'ajouter une fonction (<10 lignes) à l'aide de Lodash qui filtrent de manière récursive.