-1
votes

Filtrer un objet basé sur un autre objet

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"
//    }
//  }


2 commentaires

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.


5 Réponses :


0
votes

Vous pouvez le faire en suivant les étapes suivantes à l'aide de la récursivité:

  • Faites une copie du 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)


0 commentaires

0
votes

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)


0 commentaires

0
votes

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 )


0 commentaires

0
votes

Lodash vous permet d'utiliser très facilement la notation du point. Voici exactement ce que vous voulez (<10 lignes): xxx


0 commentaires

0
votes

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)


0 commentaires