Dans ma récente interview brutale en javascript, j'ai fait une déclaration sur les données récursives. La déclaration a été hébergée sur le GitHub. Quand j'ai vu la déclaration, j'ai ressenti un mal de tête pendant deux minutes.

Données:

const data = [
  {
    id: 1,
    object: "custom",
    url: "/services",
    title: "Services"
  },
  {
    id: 2,
    object: "dropdown",
    title: "Products",
    children: [
      {
        id: 3,
        url: "/01",
        title: "01"
      },
      {
        id: 4,
        url: "/02",
        title: "02"
      },
      {
        id: 5,
        url: "/03",
        title: "03"
      }
    ]
  },
  {
    id: 6,
    object: "page",
    url: "/work",
    title: "Work"
  },
  {
    id: 7,
    object: "page",
    url: "/contact-us",
    title: "Contact Us"
  },
  {
    id: 8,
    object: "page",
    url: "/lpc",
    title: "Lpc",
    children: [
      {
        id: 9,
        object: "page",
        url: "/pc",
        title: "pc",
        children: [
          {
            id: 10,
            object: "page",
            url: "/pop",
            title: "pop",
            children: [
              {
                id: 11,
                object: "page",
                url: "/tree",
                title: "tree"
              }
            ]
          }
        ]
      }
    ]
  }
];

Et ma tâche est d'écrire un algorithme pour convertir ces données dans le format suivant.

Les exigences sont les suivantes:

  • Chaque élément contient une propriété object qui ne peut contenir que trois valeurs. page, custom et dropdown.

  • Il n'est pas nécessaire que le type object page ou custom ait la propriété children. Mais objet avec le type dropdown est recommandé d'avoir la propriété children.

  • L'élément qui a un type object dropdown son sous-élément n'a pas pu avoir une propriété children ou object.

Le format de conversion ressemblerait à ceci :

[
  [
    {
      id: 1,
      object: "custom",
      url: "/services",
      title: "Services"
    },
    {
      id: 2,
      object: "dropdown",
      title: "Products",
      children: [
        {
          id: 3,
          url: "/01",
          title: "01"
        },
        {
          id: 4,
          url: "/02",
          title: "02"
        },
        {
          id: 5,
          url: "/03",
          title: "03"
        }
      ]
    },
    {
      id: 6,
      object: "page",
      url: "/work",
      title: "Work"
    },
    {
      id: 7,
      object: "page",
      url: "/contact-us",
      title: "Contact Us"
    },
    {
      id: 8,
      object: "page",
      url: "/lpc",
      title: "Lpc",
      children: [
        {
          id: 9,
          object: "page",
          url: "/pc",
          title: "pc",
          children: [
            {
              id: 10,
              object: "page",
              url: "/pop",
              title: "pop",
              children: [
                {
                  id: 11,
                  object: "page",
                  url: "/tree",
                  title: "tree"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  // Sub-child of the second item list on the seprate array
  [
    {
      id: 3,
      url: "/01",
      title: "01"
    },
    {
      id: 4,
      url: "/02",
      title: "02"
    },
    {
      id: 5,
      url: "/03",
      title: "03"
    }
  ],
  // Sub-child of the fifth array item on the seprate array
  [
    {
      id: 9,
      object: "page",
      url: "/pc",
      title: "pc",
      children: [
        {
          id: 10,
          object: "page",
          url: "/pop",
          title: "pop",
          children: [
            {
              id: 11,
              object: "page",
              url: "/tree",
              title: "tree"
            }
          ]
        }
      ]
    }
  ],

  // Sub-sub Child of the fifth array item on the seprate array
  [
    {
      id: 10,
      object: "page",
      url: "/pop",
      title: "pop",
      children: [
        {
          id: 11,
          object: "page",
          url: "/tree",
          title: "tree"
        }
      ]
    }
  ],

  // Sub-sub-sub child of the fifth array item on the seprate array
  [
    {
      id: 11,
      object: "page",
      url: "/tree",
      title: "tree"
    }
  ]
];

Donc, ce que j'ai compris de ce problème, c'est que je dois écrire une fonction récursive qui convertit les données dans ce format. Le format est que chaque sous-enfant de l'élément sera dans un autre tableau séparé, cela dépend des enfants de l'élément racine.

Quelle était ma solution proposée, je vais prendre 2 tableaux

  • On tiendra tous les objets qui n'ont pas d'enfants.
  • Le second contiendra tous les éléments qui contiennent des enfants.
  • En fin de compte, fusionnez ces tableaux en un seul tableau gigantesque.

Mais j'étais bloqué sur l'itération des enfants récursifs et ma solution n'a pas été générée correctement. Je l'apprécierai si vous fournissez une meilleure solution.

const data = [
  {
    id: 1,
    object: "custom",
    url: "/services",
    title: "Services"
  },
  {
    id: 2,
    object: "dropdown",
    title: "Products",
    children: [
      {
        id: 3,
        url: "/01",
        title: "01"
      },
      {
        id: 4,
        url: "/02",
        title: "02"
      },
      {
        id: 5,
        url: "/03",
        title: "03"
      }
    ]
  },
  {
    id: 6,
    object: "page",
    url: "/work",
    title: "Work"
  },
  {
    id: 7,
    object: "page",
    url: "/contact-us",
    title: "Contact Us"
  },
  {
    id: 8,
    object: "page",
    url: "/lpc",
    title: "Lpc",
    children: [
      {
        id: 9,
        object: "page",
        url: "/pc",
        title: "pc",
        children: [
          {
            id: 10,
            object: "page",
            url: "/pop",
            title: "pop",
            children: [
              {
                id: 11,
                object: "page",
                url: "/tree",
                title: "tree"
              }
            ]
          }
        ]
      }
    ]
  }
];

const arrangeData = data => {
  const temp = [];
  const arrayWithoutChild = [];
  const arrayWithChild = [];

  // ES6 for...of loop for the collection
  for (const item of data) {
    if (
      (item.object === "page" || item.object === "custom") &&
      !item.children
    ) {
      // It means it is an item without children
      temp.push({ ...item });
    }
    // Else-if block => because `object` type with dropdown has a `children` property and children item could not have any `object` and `children` property.
    else if (!item.object && !item.children) {
      // It means it is an item without children
      temp.push({ ...item });
    } else if (
      (item.object === "page" ||
        item.object === "custom" ||
        item.object === "dropdown") &&
      item.children && item.children.length > 0
    ) {
      temp.push({ ...item });
      const recursionArrayReturn = arrangeData(item.children);
      arrayWithChild.push(recursionArrayReturn);
    }
  }
  arrayWithoutChild.push([...temp]);
  return arrayWithoutChild.concat(arrayWithChild);
};

console.log("Format Data : ", arrangeData(data));
2
John Chucks 22 janv. 2020 à 20:01

1 réponse

Meilleure réponse

Ta solution est un peu compliquée. Cela peut être fait simplement avec des assistants de tableau, tout ce que la demande demande est que vous poussiez chaque tableau trouvé dans n'importe quelle profondeur dans un tableau externe. Les autres exigences me semblent un peu étrangères, l'important est simplement que s'il a une propriété children, les enfants sont poussés vers les résultats et vous les recherchez pour plus d'enfants imbriqués.

const data = [ { id: 1, object: "custom", url: "/services", title: "Services" }, { id: 2, object: "dropdown", title: "Products", children: [ { id: 3, url: "/01", title: "01" }, { id: 4, url: "/02", title: "02" }, { id: 5, url: "/03", title: "03" } ] }, { id: 6, object: "page", url: "/work", title: "Work" }, { id: 7, object: "page", url: "/contact-us", title: "Contact Us" }, { id: 8, object: "page", url: "/lpc", title: "Lpc", children: [ { id: 9, object: "page", url: "/pc", title: "pc", children: [ { id: 10, object: "page", url: "/pop", title: "pop", children: [ { id: 11, object: "page", url: "/tree", title: "tree" } ] } ] } ] } ];

const arrangeData = (arr, data) => { //this will be called with each array
  arr.push(data); //push the array, then...
  data.filter(obj => obj.children) //find elements with children
    .forEach(obj => arrangeData(arr, obj.children)); //and call this function on the child arrays
  return arr;
};

console.log(JSON.stringify(arrangeData([],data),null,2));
0
Klaycon 22 janv. 2020 à 19:25