将不均匀的数组展平为 object

flatten and uneven array into an object

我有这个数组和 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"}
      ]
    }
  ]
};

我的 objective 是扩展数组 class 使 2 个函数 flatten 将 objectExample 转换为 arrayExample 和 uneven 做相​​反的事情,我想也许lodash 会在这里提供帮助,但我仍然没有找到正确的方法,这就是我现在所在的位置:
从 objectExample 到 arrayExample 首先展平 objectExample 结构必须是特定的,这意味着 parents 必须与他们所有的 children 共享一个 属性 确保 parents 和 children 可以有其他 属性 应该移植到新数组示例中的正确项目,同样对于不均匀函数,它应该创建一个 object 所有 parents 与他们的 children 共享相同的 属性,其他 属性 应分别复制。
为了给出我的用例,我试图在我的应用程序中制作一个 d3js tree layout of angular ui router,它将从路线 JSON 文件中生成,因为我在 JSON 文件中制作路线。

更新:

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

更正:扩展 Object class 具有展平功能,将 object 展平为数组,数组 class 用 unEven 函数将一个数组 unEven 成一个 object 不像我之前写的那样:

my objective is to extend the Array class to have 2 functions.

更新 2:

为了更清楚地说明这一点,flatten 和 unEven 都类似于 map 函数,除了 flatten 用于 object 而不是数组,它 return 是一个数组,而 unEven 函数用于数组但 return 一个 object.

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

工作演示: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 原型上的一个方法(我不推荐这样做,特别是因为输入甚至不是数组)。

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