将变平和不均匀的阵列压平成对象

时间:2015-03-28 21:31:00

标签: javascript arrays d3.js lodash

我有这个Array和Object代表相同的数据:

arrayExample = [
  {name: "max", age: 21},
  {name: "max.David", age: 27},
  {name: "max.Sylvia"},
  {name: "max.David.Jeff"},
  {name: "max.Sylvia.Anna", age: 20},
  {name: "max.David.Buffy"},
  {name: "max.Sylvia.Craig"},
  {name: "max.Sylvia.Robin"}
];
ObjectExample = {
  name: "max",
  age: 21,
  children: [
    {
      name: "Sylvia",
      children: [
        {name: "Craig"},
        {name: "Robin"},
        {name: "Anna", age: 20}
      ]
    },
    {
      name: "David",
      age: 27,
      children: [
        {name: "Jeff"},
        {name: "Buffy"}
      ]
    }
  ]
};

我的目标是扩展Array类,使2个函数变平,将objectExample变换为arrayExample,并将不相反的函数反向运行,我认为也许lodash会帮助到这里,但我仍然没有找到正确的方法在这里我现在所处的位置:
要从objectExample扁平化到arrayExample,首先objectExample结构必须是特定的,这意味着父母必须与他们所有的孩子共享一个属性,确保父母和孩子可以拥有其他属性,这些属性应移植到新的arrayExample中的正确项目中,也适用于不均匀的函数它应该创建一个对象,所有父母与子女共享相同的属性,其他属性应分别复制 为了给出我的用例,我试图在我的应用程序中创建d3js tree layout angular ui router ui-router,这将从路由JSON文件生成,因为我在JSON文件中创建路由。 / p>

更新

我的具体问题是我需要为angular-ui-router配置状态对象创建一个d3js树布局,我可以将其提取到json文件中,如前所述,ui-router的结构就像arrayExample,并且d3js树布局所需的结构就像objectExample,其中一种方法是手动重写它并且它不会花费太多时间但是这个解决方案不是我想要的,我需要为此创建一个构建任务通用路由在其配置对象中始终具有name属性,可用于查找每个路由或状态的子节点,有关更多信息,请查看路由配置对象的part 1和d3 tre布局的d3视频:

更正:使用flatten函数扩展Object类以将对象展平为数组,使用unEven函数扩展Array类,以便将数组转换为不像我之前编写的对象:

  

我的目标是将Array类扩展为具有2个函数。

更新2:

为了使这一点更加清晰,flatten和unEven都像map函数,除了flatten是一个对象而不是一个数组,它返回一个数组,unEven函数是一个数组但是返回一个对象。

1 个答案:

答案 0 :(得分:1)

这是一个产生扁平输出的函数:

工作演示:http://jsfiddle.net/jfriend00/w134L7c6/

var ObjectExample = {
  name: "max",
  age: 35,
  status: "single",
  hometown: "Scottsdale",
  children: [
    {
      name: "Sylvia",
      children: [
          {name: "Craig", age: 16},
        {name: "Robin"},
        {name: "Anna"}
      ]
    },
    {
      name: "David",
      age: 54,
      children: [
        {name: "Jeff"},
        {name: "Buffy"}
      ]
    }
  ]
};

// call this on an object with a name property
// and an optional children property (which would be an array of objects)
function flatten(obj, key, outputArray, rootName) {
    var name, item;
    outputArray = outputArray || [];
    rootName = rootName || "";
    if (rootName) {
        rootName += ".";
    }
    if (obj.hasOwnProperty(key)) {
        name = rootName + obj[key];
        item = {};
        item[key] = name;
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop) && prop !== "children") {
                item[prop] = obj[prop];
            }
        }
        outputArray.push(item)
        if (obj.children) {
            for (var i = 0; i < obj.children.length; i++) {
                flatten(obj.children[i], key, outputArray, name);
            }
        }
    }
    return outputArray;
}

var result = flatten(ObjectExample, "name");

生成此输出:

[{"name":"max","age":35,"status":"single","hometown":"Scottsdale"},
{"name":"max.Sylvia"},
{"name":"max.Sylvia.Craig","age":16},
{"name":"max.Sylvia.Robin"},
{"name":"max.Sylvia.Anna"},
{"name":"max.David","age":54},
{"name":"max.David.Jeff"},
{"name":"max.David.Buffy"}]

如果你真的想要(不是我推荐的东西,特别是因为输入甚至不是一个数组)你可以调整这个函数作为Array原型的方法。

当你说&#34时,我不知道你是什么意思; rootName可以有多于一个&#34;。 ObjectExample是一个对象,因此顶级不能有多个名称。如果您从一组ObjectExample类似结构开始,那么您可以在顶层数组中的每个对象上循环调用flatten()的数组,它会累积结果。