Превратить объект с (возможными вложенными) массивами в массив объектов с массивами из одного элемента

Я пытаюсь создать рекурсивную функцию, которая может превратить этот массив:

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-объект может содержать массив, который может содержать более глубокий msg-объект, который может содержать другой массив и т. д.

Вот моя попытка, но я не могу ее понять. https://jsfiddle.net/rnacken/42e7p8hz/31/

Как вы можете видеть на скрипке, массивы вложены, родительский элемент отсутствует, а мне не хватает дочернего элемента. Боюсь, я заблудился и ошибся здесь.

почему вы хотите, чтобы он был массивом из одного объекта? Было бы удобнее, если бы вы сохранили его как объект, в чем собственно предназначение flatten?

Muhammad Faizan 11.04.2018 14:50

@MuhammadFaizan Хороший вопрос. Это, безусловно, было бы удобнее, но проект также имеет дело с асинхронным материалом, который может добавить другое (вложенное) сообщение к существующему объекту. Вопрос был предназначен для создания удобной для анализа функции ведения журнала.

rnacken 12.04.2018 10:13

хорошо, я добавил ответ .. Вы можете использовать мою функцию, это делается с помощью рекурсии, также проголосуйте за любой комментарий, который вы сочтете полезным

Muhammad Faizan 12.04.2018 11:22
2
3
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете повторить 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; }

Чистая поэзия Нина! Большое спасибо!

rnacken 12.04.2018 10:10

Я добавил простой рекурсивный подход, который вы можете использовать.

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 вы можете отображать массивы любой глубины и ожидать того же результата.

Другие вопросы по теме