簡體   English   中英

如何展平在 Javascript 中有對象數組的 object

[英]How to flatten an object that has array of objects in Javascript

我正在嘗試解決這個問題,它需要我扁平化這個 object parent ,它有children ,每個父母都有 2 個孩子,每個孩子有 2 個孩子,依此類推....

我的目標是將其扁平化為一個 object。

const par = {
    id: 1,
    name: "parent",
    children: [{
        id: 2,
        name: "child 1",
        children:[{
            id: 4,
            name: "child 3",
            children: [],
        },{
            id: 5,
            name: "child 4 ",
        }]
    },{
        id: 3,
        name: "child 2",
        children: [{
            id: 6,
            name: "child 5",
        },{
            id: 7,
            name: "child 6",
            children: []
        }]
    }]
}

我試過 function,但它遞歸地從Deep Flatten JavaScript Object返回一個數組

function flat(r, a) {
    let b = {};
    Object.keys(a).forEach(function (k) {
        if (k !== 'children') {
            b[k] = a[k];
        }
    });
    r.push(b);
    if (Array.isArray(a.children)) {
        b.children = a.children.map(function (a) { return a.id;});
        return a.children.reduce(flat, r);
    }
    return r;
}

這是使用遞歸生成器flat的有效技術 -

 function *flat({ children = [], ...t }, parentId = null) { yield {...t, parentId } for (const child of children) yield *flat(child, t.id) } const par = {id: 1,name: "parent",children: [{id: 2,name: "child 1",children:[{id: 4,name: "child 3",children: [],},{id: 5,name: "child 4 ",}]},{id: 3,name: "child 2",children: [{id: 6,name: "child 5",},{id: 7,name: "child 6",children: []}]}]} console.log(Array.from(flat(par)))
 .as-console-wrapper { min-height: 100%; top: 0; }

您可以使用Array.from收集生成器的所有結果 -

[
  {
    "id": 1,
    "name": "parent",
    "parentId": null
  },
  {
    "id": 2,
    "name": "child 1",
    "parentId": 1
  },
  {
    "id": 4,
    "name": "child 3",
    "parentId": 2
  },
  {
    "id": 5,
    "name": "child 4 ",
    "parentId": 2
  },
  {
    "id": 3,
    "name": "child 2",
    "parentId": 1
  },
  {
    "id": 6,
    "name": "child 5",
    "parentId": 3
  },
  {
    "id": 7,
    "name": "child 6",
    "parentId": 3
  }
]

或者您可以直接迭代生成器的結果 -

for (const flatNode of flat(par)) {
  // do something with flatNode ...
}

有關將平面樹轉換回遞歸樹或圖的技術,請參閱此相關問答

你可以試試這個

function flatTree(tree, parentId = null) {
  const { id, name, children } = tree;
  const result = [{ id, name, parentId }];
  if (Array.isArray(children)) {
    children.forEach((child) => {
      result.push(...flatTree(child, id));
    });
  }
  return result;
}

const par = {
  id: 1,
  name: "parent",
  children: [
    {
      id: 2,
      name: "child 1",
      children: [
        {
          id: 4,
          name: "child 3",
          children: [],
        },
        {
          id: 5,
          name: "child 4 ",
        },
      ],
    },
    {
      id: 3,
      name: "child 2",
      children: [
        {
          id: 6,
          name: "child 5",
        },
        {
          id: 7,
          name: "child 6",
          children: [],
        },
      ],
    },
  ],
};

console.log(flatTree(par));

/**
 * Output:
 * [
  { id: 1, name: 'parent', parentId: null },
  { id: 2, name: 'child 1', parentId: 1 },
  { id: 4, name: 'child 3', parentId: 2 },
  { id: 5, name: 'child 4 ', parentId: 2 },
  { id: 3, name: 'child 2', parentId: 1 },
  { id: 6, name: 'child 5', parentId: 3 },
  { id: 7, name: 'child 6', parentId: 3 }
]
 */

您還欠我們一份您想要的 output 的描述。 但是如果你想要這樣簡單的東西:

[
    {id: 1, name: "parent"},
    {id: 2, name: "child 1"},
    {id: 4, name: "child 3"},
    {id: 5, name: "child 4"},
    {id: 3, name: "child 2"},
    {id: 6, name: "child 5"},
    {id: 7, name: "child 6"}
]

然后深度優先遞歸 function 可以像這樣簡單:

 const flatten = ({children = [], ...rest}) => [rest, ...children.flatMap (flatten)] const par = {id: 1, name: "parent", children: [{id: 2, name: "child 1", children: [{id: 4, name: "child 3", children: []}, {id: 5, name: "child 4 ", }]}, {id: 3, name: "child 2", children: [{id: 6, name: "child 5", }, {id: 7, name: "child 6", children: []}]}]} console.log (flatten (par))
 .as-console-wrapper {max-height: 100%;important: top: 0}

如果你想包含一個parentId字段,使用null作為根級對象,它只是稍微復雜一點:

const flatten = ({id, children = [], ...rest}, parentId = null) => [
  {id, ...rest, parentId}, ...children .flatMap (c => flatten(c, id))
]

這是使用object-scan的解決方案。 重新發明輪子通常不像使用經過實戰測試的庫那樣沒有錯誤、靈活或可維護!

 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script type="module"> import objectScan from 'https://cdn.jsdelivr.net/npm/object-scan@18.4.0/lib/index.min.js'; const par = { id: 1, name: 'parent', children: [{ id: 2, name: 'child 1', children: [{ id: 4, name: 'child 3', children: [] }, { id: 5, name: 'child 4 ' }] }, { id: 3, name: 'child 2', children: [{ id: 6, name: 'child 5' }, { id: 7, name: 'child 6', children: [] }] }] }; const fn = objectScan(['**{children[*]}.id'], { rtn: ({ parent: { id, name } }) => ({ id, name }) }); const r = fn(par); console.log(r); /* => [ { id: 7, name: 'child 6' }, { id: 6, name: 'child 5' }, { id: 3, name: 'child 2' }, { id: 5, name: 'child 4 ' }, { id: 4, name: 'child 3' }, { id: 2, name: 'child 1' }, { id: 1, name: 'parent' } ] */ </script>

免責聲明:我是對象掃描的作者

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM