【问题标题】:Turn object with (possible nested) arrays into an array of objects with single-item arrays将具有(可能嵌套的)数组的对象转换为具有单项数组的对象数组
【发布时间】:2018-04-11 10:41:45
【问题描述】:

我正在尝试创建一个可以翻转这个数组的递归函数:

const originalObj = {
    field: "parent",
    msg:[{
        field: "child1a",
        msg: [{
            field: "child2a",
            msg: "child2a-msg"
        },
        {
            field: "child2b",
            msg: "child2b-msg"
        }
      ]
    }, {
        field: "child1b",
        msg: "child1b-msg"
    }
  ]
};

进入这个:

[
    {
    field: "parent",
    msg: [
      {
        field: "child1a",
        msg: [
          {
            field: "child2a",
            msg: "child2a-msg"
          }
        ]  
      },
    ]
    },
  {
    field: "parent",
    msg: [
      {
        field: "child1a",
        msg: [
          {
            field: "child2b",
            msg: "child2b-msg"
          }
        ]  
      },
    ]
    },
  {
    field: "parent",
    msg: [
        {
        field: "child1b",
        msg: "child1b-msg"
      }
    ]
  }
]

所以,要明确一点:msg 对象可以是字符串或单项数组。

应该是递归的;因为一个 msg-object 可以包含一个数组,它可以包含一个更深的 msg-object,它可以包含另一个数组,等等。

这是我的尝试,但我无法弄清楚。 https://jsfiddle.net/rnacken/42e7p8hz/31/

正如您在小提琴中看到的,数组是嵌套的,缺少父级,而我缺少一个子级。恐怕我迷路了,走错了路。

【问题讨论】:

  • 为什么要将它作为单个对象的数组?如果你把它保存为一个对象会更方便,这就是flatten的实际目的?
  • @MuhammadFaizan 好问题。那肯定会更方便,但该项目还处理可能向现有对象添加另一个(嵌套)消息的异步内容。该问题旨在创建一个易于解析的日志记录功能。
  • 好的,我已经添加了答案.. 你可以使用我的函数,它是通过递归完成的,也可以投票任何你认为有帮助的评论

标签: javascript arrays recursion


【解决方案1】:

您可以迭代msg 并构建嵌套项的新嵌套部分结果。然后迭代并为结果数组构建单个对象。

function getSingle({ field, msg }) {
    var array = [];

    if (!msg || !Array.isArray(msg)) {
        return [{ field, msg }];
    }
    msg.forEach(o => getSingle(o).forEach(s => array.push({ field, msg: [s] })));
    return array;
}

var object = { field: "parent", msg: [{ field: "child1a", msg: [{ field: "child2a", msg: [{ field: "child3a", msg: "child3a-msg" }, { field: "child3b", msg: "child3b-msg" }] }, { field: "child2b", msg: "child2b-msg" }] }, { field: "child1b", msg: "child1b-msg" }] };

console.log(getSingle(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 纯诗妮娜!非常感谢!
【解决方案2】:

我添加了一个简单的递归方法供您使用。

const originalObj = {
    field: "parent",
    msg: [
    {
        field: "child1a",
        msg: [
        {
            field: "child2a",
            msg: "child2a-msg"
        },
        {
            field: "child2b",
            msg: "child2b-msg"
        }
      ]
    },
    {
      field: "child1b",
      msg: "child1b-msg"
    }
  ]
};

const flatten = ({field, msg}) =>  {
    const res = []; // creating an array to create the msg array in case of multiple entries in msg
    if (typeof msg === "string") {
        return {field, msg}; // return plain object if the msg is "string"
    }
    if (msg.constructor === Array) {
        // recursion here
        msg.map(message => flatten(message, msg))
        .forEach(m => {
            // after flattening array msg, we push them to msg field
            res.push({field, msg: m})
        });
    }
    return res; // returning final result here
}
const newObj = flatten(originalObj);

使用flatten 函数,您可以映射任意深度的数组并期望得到相同的结果。

【讨论】: