2013-08-08 3 views
0

J'ai un objet JavaScript imbriqué complexe avec moi. L'exigence est d'aplatir complètement l'objet ou seulement certains des membres qui le composent.Toute bibliothèque JavaScript standard pour la transformation d'objets JS

var obj = { 
    a: { 
     b: { 
      c: { 
      d: "Varun" 
      }, 
      e: "kumar" 
     } 
    } 
}; 

L'objet qu'on peut en attendre:

{d: "Varun", e: "kumar"} 

Je l'ai écrit d'une simple transformation utilitaire qui accepte la carte accesseur sous la forme { « ABCD »: « d »} et transformer l'objet dans le nouvel objet. Je ne supporte pas les tableaux pour l'instant. En outre, l'utilitaire de transformation peut uniquement réduire un objet complexe en un objet plus simple et non l'inverse (c'est-à-dire construire un nouvel objet membre à partir d'un simple membre).

"use strict"; 
var ObjectUtil = (function() { 
    // constructor 
    var cls = function() { 

    }; 

    // public static 
    cls.getValueFromAccessor = function (obj, accessor) { 
     if (obj == null || accessor == null) 
      return null; 

     return accessor.split(".").reduce(function(prev, current, index) { 
      var reducedObject = prev; 
      if (index == 1) 
       reducedObject = obj[prev]; 

      if (reducedObject == null) 
       return null; 

      return reducedObject[current]; 
     }); 
    }; 

    cls.transform = function(obj, accessorMap, overlay) { 
     var result; 

     if (overlay) 
      result = obj; 
     else 
      result = {}; 

     for (var k in accessorMap) { 
      result[accessorMap[k]] = cls.getValueFromAccessor(obj, k); 
     } 

     return result; 
    }; 

    return cls; 
})(); 

var obj = { 
    a: { 
     b: { 
      c: { 
      d: "Varun" 
      }, 
      e: "kumar" 
     } 
    } 
}; 

var accessorMap = { 
    "a.b.c.d": "d", 
    "a.b.e": "e" 
} 

ObjectUtil.getValueFromAccessor(obj, "a.b.c.d"); 
console.log(ObjectUtil.transform(obj, accessorMap, false)); 
console.log(ObjectUtil.transform(obj, accessorMap, true)); 

Existe-t-il un moyen standard de transformer des objets d'une forme à une autre. Toutes les bibliothèques disponibles pour cela?

+0

[Il n'existe pas d'objet JSON] (http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/). Votre problème n'a * rien * à voir avec JSON * du tout *. Et JavaScript n'a pas de bibliothèque standard. –

+0

Oui, je comprends cela. Mon mauvais pour les utiliser de façon interchangeable. –

+0

underscore.js est une bibliothèque largement utilisée pour faire des choses comme ça. Cueillir des propriétés spécifiques, aplanir des collections, mapper/réduire, etc. –

Répondre

0
var converter = new (function(){ 
    var divider = "."; 
    var doFlatten = function(source, path, newObj){ 
     for(var i in source){ 
      if(source.hasOwnProperty(i)){ 
       var tempPath = (path == "") ? i : path + divider + i; 
       if(typeof source[i] == "object"){ 
        doFlatten(source[i], tempPath, newObj); 
       } 
       else{ 
        newObj[tempPath] = source[i]; 
       } 
      } 
     } 
    }; 
    this.flatten = function(source){ 
     if(typeof source == "object"){ 
      var newObj = {}; 
      doFlatten(source, "", newObj); 
      return newObj; 
     } 
     return source; 
    }; 
    this.expand = function(source){ 
     var dest = {}; 
     if(typeof source == "object"){ 
      for(var i in source){ 
       if(source.hasOwnProperty(i)){ 
        var path = i.split(divider); 
        var temp = dest; 
        var prevTemp = dest; 
        for(var j in path){ 
         if(!temp.hasOwnProperty(path[j])){ 
          temp[path[j]] = {}; 
         } 
         prevTemp = temp; 
         temp = temp[path[j]]; 
        } 
        prevTemp[path[path.length - 1]] = source[i]; 
       } 
      } 
      return dest; 
     } 
     return source; 
    }; 
}); 

Utilisation:

var flatObj = converter.flatten({ 
    a: { 
     b: { 
      c: { 
       d: "Varun" 
      }, 
      e: "kumar" 
     } 
    } 
}); 
console.log(flatObj); 
// {"a.b.c.d": "Varun", "a.b.e": "kumar"} 

var expanded = converter.expand(flatObj); 
console.log(expanded); 
// { 
// a: { 
//  b: { 
//   c: { 
//    d: "Varun" 
//   }, 
//   e: "kumar" 
//  } 
// } 
// } 
0

Jetez un oeil à js-api-smith, il offre des transformations d'objets JavaScript de manière déclarative. Il peut être installé comme NPM package, si vous l'utilisez dans le navigateur, vous pouvez utiliser browserify.

Voici un exemple de résoudre le problème dans votre question:

const apiSmith = require('js-api-smith'); 
 

 
// one way 
 
const transformations1 = { 
 
    d: "a.b.c.d", 
 
    // d: ["a", "b", "c", "d"], // can also be written this way 
 
    e: "a.b.e" 
 
}; 
 

 
const from1 = { 
 
    a: { 
 
    b: { 
 
     c: { 
 
     d: "Varun" 
 
     }, 
 
     e: "kumar" 
 
    } 
 
    } 
 
}; 
 

 
const transformed1 = apiSmith.smash(transformations1, from1); 
 
// -> { d: "Varun", e: "kumar" } 
 

 
// or the other way 
 
const transformations2 = { 
 
    "a.b.c.d": "d", 
 
    "a.b.e": "e" 
 
}; 
 

 
const from2 = { d: "Varun", e: "kumar" }; 
 

 
const transformed2 = apiSmith.smash(transformations2, from2); 
 
// -> { 
 
// a: { 
 
//  b: { 
 
//  c: { 
 
//   d: "Varun" 
 
//  }, 
 
//  e: "kumar" 
 
//  } 
 
// } 
 
// };

La lib supporte également la configuration par défaut et en spécifiant les fonctions de transformation sur les propriétés, vous pouvez vérifier the documentations si vous êtes intéressé.

Espérons que cela aide.

Questions connexes