简体   繁体   中英

How to flatten a tree with TypeScript

I have this TypeScript code:

function flattenTree <T, K extends keyof T>(tree: T, key: K): T[] {
  const flattedTree = {
    ...tree,
  };
  delete flattedTree[key];

  if (Array.isArray(tree[key]) && (tree[key] as any as T[]).length > 0) {
    return [flattedTree].concat(
      (tree[key] as any as T[]).map(child => flattenTree(child, key))
        .reduce((pre, next) => pre.concat(next)),
    );
  }

  return [flattedTree];
}

Input:

interface ShopTree {
  shopId: string;
  name: string;
  nodeType: string;
  children: ShopTree[];
}
const testObj: ShopTree = {
  shopId: '123',
  name: 'KFC(root)',
  nodeType: 'ROOT‘,
  children: [
    {
      shopId: '23',
      name: 'KFC(middle)',
      nodeType: 'MIDDLE',
      children: [{
        shopId: '45',
        name: 'KFC(leafA)',
        nodeType: 'LEAF’,
      }]
    },
    {
      shopId: '234',
      name: 'KFC(leafB)',
      nodeType: 'LEAF’,
    }
  ]
}

Output:

console.log('result', flattenTree(testObj))

[
  {
    shopId: '123',
    name: 'KFC(root)',
    nodeType: 'ROOT‘,
  },
  {
    shopId: '23',
    name: 'KFC(middle)',
    nodeType: 'MIDDLE',
  },
  {
    shopId: '45',
    name: 'KFC(leafA)',
    nodeType: 'LEAF’,
  }
  ....
]

Could someone give me an idea of how to write the right types for the function?

While the output has no property value of children and I don't want to use as any as xxx in the code.

Could someone give me an idea of how to write the right types for the function?

While the output has no property value of children and I don't want to use as any as xxx in the code.

Without seeing how your tree is structured, it's a little difficult to provide any more precise help. Here's an example of how the type might look:

const flattenTree = <T>(tree: INode<T> | null): T[] => tree === null
    ? []
    : [tree.value, ...flattenTree(tree.left), ...flattenTree(tree.right)]

A flattened tree of <T> returns T[]


Here's a full example of how that would flatten a tree:

interface INode<T> {
    left: INode<T> | null;
    right: INode<T> | null;
    value: T;
}

const flattenTree = <T>(tree: INode<T> | null): T[] => tree === null
    ? []
    : [tree.value, ...flattenTree(tree.left), ...flattenTree(tree.right)]

const testTree: INode<number> = {
    left: {
        left: null,
        right: {
            left: null,
            right: {
                left: null,
                right: null,
                value: 7,
            },
            value: 5,
        },
        value: 3,
    },
    right: {
        right: {
            left: {
                left: null,
                right: null,
                value: 0,
            },
            right: null,
            value: 9,
        },
        left: {
            right: null,
            left: null,
            value: 1,
        },
        value: 10,
    },
    value: 2,
};

const result = flattenTree(testTree);
console.log(result); 
/* gives:
0: 2
1: 3
2: 5
3: 7
4: 10
5: 1
6: 9
7: 0
*/

Typescript playground link.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM