0

我有一个复杂的嵌套 JavaScript 对象。要求是完全展平对象或仅展平其中的一些成员。

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

预期的结果对象:

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

我编写了一个简单的转换实用程序,它将接受 {"abcd": "d"} 形式的访问器映射并将对象转换为新对象。我暂时不支持数组。此外,转换实用程序只能将复杂对象简化为更简单的对象,反之亦然(即从简单成员构造新成员对象)。

"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));

是否有将对象从一种形式转换为另一种形式的标准方法。有任何可用的库吗?

4

2 回答 2

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;
    };
});

用法:

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"
//        }
//    }   
// }
于 2013-08-08T11:42:06.120 回答
0

看看js-api-smith,它以声明的方式提供 JavaScript 对象的转换。它可以作为NPM 包安装,如果你在浏览器中使用它,你可以使用browserify

这是解决您问题中的问题的示例:

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

该库还支持在属性上设置默认值和指定转换函数,如果您有兴趣,可以查看文档。

希望这可以帮助。

于 2017-03-23T07:01:41.123 回答