@anastasia__galkina

Как преобразовать древовидный массив в плоский?

Есть древовидный массив:
[
  {
    "task": "Project: Shopping",
    "duration": 13.25,
    "user": "Tommy Maintz",
    "iconCls": "task-folder",
    "expanded": true,
    "children": [
      {
        "task": "Housewares",
        "duration": 1.25,
        "user": "Tommy Maintz",
        "iconCls": "task-folder",
        "children": [
          {
            "task": "Kitchen supplies",
            "duration": 0.25,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task"
          }, {
            "task": "Groceries",
            "duration": .4,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task",
            "done": true
          }, {
            "task": "Cleaning supplies",
            "duration": .4,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task"
          }, {
            "task": "Office supplies",
            "duration": .2,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task"
          }
        ]
      }, {
        "task": "Remodeling",
        "duration": 12,
        "user": "Tommy Maintz",
        "iconCls": "task-folder",
        "expanded": true,
        "children": [
          {
            "task": "Retile kitchen",
            "duration": 6.5,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task"
          }, {
            "task": "Paint bedroom",
            "duration": 2.75,
            "user": "Tommy Maintz",
            "iconCls": "task-folder",
            "children": [
              {
                "task": "Ceiling",
                "duration": 1.25,
                "user": "Tommy Maintz",
                "iconCls": "task",
                "leaf": true
              }, {
                "task": "Walls",
                "duration": 1.5,
                "user": "Tommy Maintz",
                "iconCls": "task",
                "leaf": true
              }
            ]
          }, {
            "task": "Decorate living room",
            "duration": 2.75,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task",
            "done": true
          }, {
            "task": "Fix lights",
            "duration": .75,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task",
            "done": true
          }, {
            "task": "Reattach screen door",
            "duration": 2,
            "user": "Tommy Maintz",
            "leaf": true,
            "iconCls": "task"
          }
        ]
      }
    ]
  }, {
    "task": "Project: Testing",
    "duration": 2,
    "user": "Core Team",
    "iconCls": "task-folder",
    "children": [
      {
        "task": "Mac OSX",
        "duration": 0.75,
        "user": "Tommy Maintz",
        "iconCls": "task-folder",
        "children": [
          {
            "task": "FireFox",
            "duration": 0.25,
            "user": "Tommy Maintz",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Safari",
            "duration": 0.25,
            "user": "Tommy Maintz",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Chrome",
            "duration": 0.25,
            "user": "Tommy Maintz",
            "iconCls": "task",
            "leaf": true
          }
        ]
      }, {
        "task": "Windows",
        "duration": 3.75,
        "user": "Darrell Meyer",
        "iconCls": "task-folder",
        "children": [
          {
            "task": "FireFox",
            "duration": 0.25,
            "user": "Darrell Meyer",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Safari",
            "duration": 0.25,
            "user": "Darrell Meyer",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Chrome",
            "duration": 0.25,
            "user": "Darrell Meyer",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Internet Explorer",
            "duration": 3,
            "user": "Darrell Meyer",
            "iconCls": "task",
            "leaf": true
          }
        ]
      }, {
        "task": "Linux",
        "duration": 0.5,
        "user": "Aaron Conran",
        "iconCls": "task-folder",
        "children": [
          {
            "task": "FireFox",
            "duration": 0.25,
            "user": "Aaron Conran",
            "iconCls": "task",
            "leaf": true
          }, {
            "task": "Chrome",
            "duration": 0.25,
            "user": "Aaron Conran",
            "iconCls": "task",
            "leaf": true
          }
        ]
      }
    ]
  }
]

Вложенные массивы находятся в поле children.

Нужно преобразовать данный массив в плоский такого вида:

[
  {
    "task": "Project: Shopping",
    "duration": 13.25,
    "user": "Tommy Maintz",
    "iconCls": "task-folder",
    "expanded": true,
  }, 
  {
    "task": "Housewares",
    "duration": 1.25,
    "user": "Tommy Maintz",
    "iconCls": "task-folder",
  }, 
  { 
    "task": "Kitchen supplies",
    "duration": 0.25,
    "user": "Tommy Maintz",
    "leaf": true,
    "iconCls": "task"
  },
  ...
]
  • Вопрос задан
  • 151 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Рекурсия есть:

const flat = (arr, childrenKey) =>
  arr instanceof Array
    ? arr.flatMap(({ [childrenKey]: c, ...n }) => [ n, ...flat(c, childrenKey) ])
    : [];


const result = flat(items, 'children');

Рекурсии нет:

function flat(arr, childrenKey) {
  const result = [];

  for (const stack = [...arr].reverse(); stack.length;) {
    const { [childrenKey]: c, ...n } = stack.pop();

    if (Array.isArray(c) && c.length) {
      stack.push(...[...c].reverse());
    }

    result.push(n);
  }

  return result;
}

// или

function flat(arr, childrenKey) {
  const result = [];
  const stack = [];

  for (let i = 0; i < arr.length || stack.length; i++) {
    if (i === arr.length) {
      [ i, arr ] = stack.pop();
    } else {
      const { [childrenKey]: c, ...n } = arr[i];

      if (c?.constructor === Array && c.length) {
        stack.push([ i, arr ]);
        [ i, arr ] = [ -1, c ];
      }

      result.push(n);
    }
  }

  return result;
}

// или

function flat([...arr], childrenKey) {
  for (const [ i, { [childrenKey]: c, ...n } ] of arr.entries()) {
    arr.splice(i, 1, n, ...(c?.[Symbol.iterator] && typeof c !== 'string' ? c : []));
  }

  return arr;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
21 нояб. 2024, в 19:31
500 руб./за проект
21 нояб. 2024, в 19:28
200000 руб./за проект