【TypeScript】フラットなデータ構造をdepthによってネストしたデータ構造にする
ネストしたデータ構造をフラットなデータにする方法は検索すれば、たくさん出てきます。しかし、フラットなデータをネストしたデータに変換するような記事はなかなか見当たりません。今回はそれをどうやってコードで実現するのかTypeScriptで考えてみようと思います。
【TypeScript】フラットなデータ構造をdepthによってネストしたデータ構造にするネストしたデータ構造をフラットなデータにする方法は検索すれば、たくさん出てきます。しかし、フラットなデータをネストしたデータに変換するような記事はなかなか見当たりません。今回はそれをどうやってコードで実現するのかTypeScriptで考えてみようと思います。
%3btext-align:center%3b%7d%23mermaid-0 .edgeLabel p%7bbackground-color:rgba(232%2c232%2c232%2c 0.8)%3b%7d%23mermaid-0 .edgeLabel rect%7bopacity:0.5%3bbackground-color:rgba(232%2c232%2c232%2c 0.8)%3bfill:rgba(232%2c232%2c232%2c 0.8)%3b%7d%23mermaid-0 .labelBkg%7bbackground-color:rgba(232%2c 232%2c 232%2c 0.5)%3b%7d%23mermaid-0 .cluster rect%7bfill:%23ffffde%3bstroke:%23aaaa33%3bstroke-width:1px%3b%7d%23mermaid-0 .cluster text%7bfill:%23333%3b%7d%23mermaid-0 .cluster span%7bcolor:%23333%3b%7d%23mermaid-0 div.mermaidTooltip%7bposition:absolute%3btext-align:center%3bmax-width:200px%3bpadding:2px%3bfont-family:arial%2csans-serif%3bfont-size:12px%3bbackground:hsl(80%2c 100%25%2c 96.2745098039%25)%3bborder:1px solid %23aaaa33%3bborder-radius:2px%3bpointer-events:none%3bz-index:100%3b%7d%23mermaid-0 .flowchartTitleText%7btext-anchor:middle%3bfont-size:18px%3bfill:%23333%3b%7d%23mermaid-0 rect.text%7bfill:none%3bstroke-width:0%3b%7d%23mermaid-0 .icon-shape%2c%23mermaid-0 .image-shape%7bbackground-color:rgba(232%2c232%2c232%2c 0.8)%3btext-align:center%3b%7d%23mermaid-0 .icon-shape p%2c%23mermaid-0 .image-shape p%7bbackground-color:rgba(232%2c232%2c232%2c 0.8)%3bpadding:2px%3b%7d%23mermaid-0 .icon-shape .label rect%2c%23mermaid-0 .image-shape .label rect%7bopacity:0.5%3bbackground-color:rgba(232%2c232%2c232%2c 0.8)%3bfill:rgba(232%2c232%2c232%2c 0.8)%3b%7d%23mermaid-0 .label-icon%7bdisplay:inline-block%3bheight:1em%3boverflow:visible%3bvertical-align:-0.125em%3b%7d%23mermaid-0 .node .label-icon path%7bfill:currentColor%3bstroke:revert%3bstroke-width:revert%3b%7d%23mermaid-0 .node .neo-node%7bstroke:%239370DB%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node rect%2c%23mermaid-0 %5bdata-look='neo'%5d.cluster rect%2c%23mermaid-0 %5bdata-look='neo'%5d.node polygon%7bstroke:%239370DB%3bfilter:drop-shadow(1px 2px 2px rgba(185%2c 185%2c 185%2c 1))%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.swimlane.cluster rect%7bfilter:none%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node path%7bstroke:%239370DB%3bstroke-width:1px%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node .outer-path%7bfilter:drop-shadow(1px 2px 2px rgba(185%2c 185%2c 185%2c 1))%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node .neo-line path%7bstroke:%239370DB%3bfilter:none%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node circle%7bstroke:%239370DB%3bfilter:drop-shadow(1px 2px 2px rgba(185%2c 185%2c 185%2c 1))%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.node circle .state-start%7bfill:black%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.icon-shape .icon%7bfill:%239370DB%3bfilter:drop-shadow(1px 2px 2px rgba(185%2c 185%2c 185%2c 1))%3b%7d%23mermaid-0 %5bdata-look='neo'%5d.icon-shape .icon-neo path%7bstroke:%239370DB%3bfilter:drop-shadow(1px 2px 2px rgba(185%2c 185%2c 185%2c 1))%3b%7d%23mermaid-0 :root%7b--mermaid-font-family:arial%2csans-serif%3b%7d%3c/style%3e%3cg%3e%3cmarker id='mermaid-0_flowchart-v2-pointEnd' class='marker flowchart-v2' viewBox='0 0 10 10' refX='5' refY='5' markerUnits='userSpaceOnUse' markerWidth='8' markerHeight='8' orient='auto'%3e%3cpath d='M 0 0 L 10 5 L 0 10 z' class='arrowMarkerPath' style='stroke-width: 1%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-pointStart' class='marker flowchart-v2' viewBox='0 0 10 10' refX='4.5' refY='5' markerUnits='userSpaceOnUse' markerWidth='8' markerHeight='8' orient='auto'%3e%3cpath d='M 0 5 L 10 10 L 10 0 z' class='arrowMarkerPath' style='stroke-width: 1%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-pointEnd-margin' class='marker flowchart-v2' viewBox='0 0 11.5 14' refX='11.5' refY='7' markerUnits='userSpaceOnUse' markerWidth='10.5' markerHeight='14' orient='auto'%3e%3cpath d='M 0 0 L 11.5 7 L 0 14 z' class='arrowMarkerPath' style='stroke-width: 0%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-pointStart-margin' class='marker flowchart-v2' viewBox='0 0 11.5 14' refX='1' refY='7' markerUnits='userSpaceOnUse' markerWidth='11.5' markerHeight='14' orient='auto'%3e%3cpolygon points='0%2c7 11.5%2c14 11.5%2c0' class='arrowMarkerPath' style='stroke-width: 0%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-circleEnd' class='marker flowchart-v2' viewBox='0 0 10 10' refX='11' refY='5' markerUnits='userSpaceOnUse' markerWidth='11' markerHeight='11' orient='auto'%3e%3ccircle cx='5' cy='5' r='5' class='arrowMarkerPath' style='stroke-width: 1%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-circleStart' class='marker flowchart-v2' viewBox='0 0 10 10' refX='-1' refY='5' markerUnits='userSpaceOnUse' markerWidth='11' markerHeight='11' orient='auto'%3e%3ccircle cx='5' cy='5' r='5' class='arrowMarkerPath' style='stroke-width: 1%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-circleEnd-margin' class='marker flowchart-v2' viewBox='0 0 10 10' refY='5' refX='12.25' markerUnits='userSpaceOnUse' markerWidth='14' markerHeight='14' orient='auto'%3e%3ccircle cx='5' cy='5' r='5' class='arrowMarkerPath' style='stroke-width: 0%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-circleStart-margin' class='marker flowchart-v2' viewBox='0 0 10 10' refX='-2' refY='5' markerUnits='userSpaceOnUse' markerWidth='14' markerHeight='14' orient='auto'%3e%3ccircle cx='5' cy='5' r='5' class='arrowMarkerPath' style='stroke-width: 0%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-crossEnd' class='marker cross flowchart-v2' viewBox='0 0 11 11' refX='12' refY='5.2' markerUnits='userSpaceOnUse' markerWidth='11' markerHeight='11' orient='auto'%3e%3cpath d='M 1%2c1 l 9%2c9 M 10%2c1 l -9%2c9' class='arrowMarkerPath' style='stroke-width: 2%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-crossStart' class='marker cross flowchart-v2' viewBox='0 0 11 11' refX='-1' refY='5.2' markerUnits='userSpaceOnUse' markerWidth='11' markerHeight='11' orient='auto'%3e%3cpath d='M 1%2c1 l 9%2c9 M 10%2c1 l -9%2c9' class='arrowMarkerPath' style='stroke-width: 2%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-crossEnd-margin' class='marker cross flowchart-v2' viewBox='0 0 15 15' refX='17.7' refY='7.5' markerUnits='userSpaceOnUse' markerWidth='12' markerHeight='12' orient='auto'%3e%3cpath d='M 1%2c1 L 14%2c14 M 1%2c14 L 14%2c1' class='arrowMarkerPath' style='stroke-width: 2.5%3b'/%3e%3c/marker%3e%3cmarker id='mermaid-0_flowchart-v2-crossStart-margin' class='marker cross flowchart-v2' viewBox='0 0 15 15' refX='-3.5' refY='7.5' markerUnits='userSpaceOnUse' markerWidth='12' markerHeight='12' orient='auto'%3e%3cpath d='M 1%2c1 L 14%2c14 M 1%2c14 L 14%2c1' class='arrowMarkerPath' style='stroke-width: 2.5%3b stroke-dasharray: 1%2c 0%3b'/%3e%3c/marker%3e%3cg class='root'%3e%3cg class='clusters'/%3e%3cg class='edgePaths'%3e%3cpath d='M48.672%2c62L48.672%2c66.167C48.672%2c70.333%2c48.672%2c78.667%2c48.672%2c86.333C48.672%2c94%2c48.672%2c101%2c48.672%2c104.5L48.672%2c108' id='mermaid-0-L_A_AA_0' class='edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link' style='%3b' data-edge='true' data-et='edge' data-id='L_A_AA_0' data-points='W3sieCI6NDguNjcxODc1LCJ5Ijo2Mn0seyJ4Ijo0OC42NzE4NzUsInkiOjg3fSx7IngiOjQ4LjY3MTg3NSwieSI6MTEyfV0=' data-look='classic' marker-end='url(%23mermaid-0_flowchart-v2-pointEnd)'/%3e%3cpath d='M180.016%2c62L180.016%2c66.167C180.016%2c70.333%2c180.016%2c78.667%2c180.016%2c86.333C180.016%2c94%2c180.016%2c101%2c180.016%2c104.5L180.016%2c108' id='mermaid-0-L_B_BB_0' class='edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link' style='%3b' data-edge='true' data-et='edge' data-id='L_B_BB_0' data-points='W3sieCI6MTgwLjAxNTYyNSwieSI6NjJ9LHsieCI6MTgwLjAxNTYyNSwieSI6ODd9LHsieCI6MTgwLjAxNTYyNSwieSI6MTEyfV0=' data-look='classic' marker-end='url(%23mermaid-0_flowchart-v2-pointEnd)'/%3e%3cpath d='M180.016%2c166L180.016%2c170.167C180.016%2c174.333%2c180.016%2c182.667%2c180.016%2c190.333C180.016%2c198%2c180.016%2c205%2c180.016%2c208.5L180.016%2c212' id='mermaid-0-L_BB_BBB_0' class='edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link' style='%3b' data-edge='true' data-et='edge' data-id='L_BB_BBB_0' data-points='W3sieCI6MTgwLjAxNTYyNSwieSI6MTY2fSx7IngiOjE4MC4wMTU2MjUsInkiOjE5MX0seyJ4IjoxODAuMDE1NjI1LCJ5IjoyMTZ9XQ==' data-look='classic' marker-end='url(%23mermaid-0_flowchart-v2-pointEnd)'/%3e%3c/g%3e%3cg class='edgeLabels'%3e%3cg class='edgeLabel'%3e%3cg class='label' data-id='L_A_AA_0' transform='translate(0%2c 0)'%3e%3cforeignObject width='0' height='0'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' class='labelBkg' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='edgeLabel'%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='edgeLabel'%3e%3cg class='label' data-id='L_B_BB_0' transform='translate(0%2c 0)'%3e%3cforeignObject width='0' height='0'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' class='labelBkg' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='edgeLabel'%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='edgeLabel'%3e%3cg class='label' data-id='L_BB_BBB_0' transform='translate(0%2c 0)'%3e%3cforeignObject width='0' height='0'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' class='labelBkg' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='edgeLabel'%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg class='nodes'%3e%3cg class='node default' id='mermaid-0-flowchart-A-0' data-look='classic' transform='translate(48.671875%2c 35)'%3e%3crect class='basic label-container' style='' x='-35.3359375' y='-27' width='70.671875' height='54'/%3e%3cg class='label' style='' transform='translate(-5.3359375%2c -12)'%3e%3crect/%3e%3cforeignObject width='10.671875' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eA%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='node default' id='mermaid-0-flowchart-AA-1' data-look='classic' transform='translate(48.671875%2c 139)'%3e%3crect class='basic label-container' style='' x='-40.671875' y='-27' width='81.34375' height='54'/%3e%3cg class='label' style='' transform='translate(-10.671875%2c -12)'%3e%3crect/%3e%3cforeignObject width='21.34375' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eAA%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='node default' id='mermaid-0-flowchart-B-2' data-look='classic' transform='translate(180.015625%2c 35)'%3e%3crect class='basic label-container' style='' x='-35.3359375' y='-27' width='70.671875' height='54'/%3e%3cg class='label' style='' transform='translate(-5.3359375%2c -12)'%3e%3crect/%3e%3cforeignObject width='10.671875' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eB%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='node default' id='mermaid-0-flowchart-BB-3' data-look='classic' transform='translate(180.015625%2c 139)'%3e%3crect class='basic label-container' style='' x='-40.671875' y='-27' width='81.34375' height='54'/%3e%3cg class='label' style='' transform='translate(-10.671875%2c -12)'%3e%3crect/%3e%3cforeignObject width='21.34375' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eBB%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='node default' id='mermaid-0-flowchart-BBB-5' data-look='classic' transform='translate(180.015625%2c 243)'%3e%3crect class='basic label-container' style='' x='-46.0078125' y='-27' width='92.015625' height='54'/%3e%3cg class='label' style='' transform='translate(-16.0078125%2c -12)'%3e%3crect/%3e%3cforeignObject width='32.015625' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eBBB%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3cg class='node default' id='mermaid-0-flowchart-C-6' data-look='classic' transform='translate(301.1328125%2c 35)'%3e%3crect class='basic label-container' style='' x='-35.78125' y='-27' width='71.5625' height='54'/%3e%3cg class='label' style='' transform='translate(-5.78125%2c -12)'%3e%3crect/%3e%3cforeignObject width='11.5625' height='24'%3e%3cdiv xmlns='http://www.w3.org/1999/xhtml' style='display: table-cell%3b white-space: nowrap%3b line-height: 1.5%3b max-width: 200px%3b text-align: center%3b'%3e%3cspan class='nodeLabel'%3e%3cp%3eC%3c/p%3e%3c/span%3e%3c/div%3e%3c/foreignObject%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter id='mermaid-0-drop-shadow' height='130%25' width='130%25'%3e%3cfeDropShadow dx='4' dy='4' stdDeviation='0' flood-opacity='0.06' flood-color='black'/%3e%3c/filter%3e%3c/defs%3e%3cdefs%3e%3cfilter id='mermaid-0-drop-shadow-small' height='150%25' width='150%25'%3e%3cfeDropShadow dx='2' dy='2' stdDeviation='0' flood-opacity='0.06' flood-color='black'/%3e%3c/filter%3e%3c/defs%3e%3c/svg%3e)
main.test.ts
Terminal window
はじめに
ネストしたデータ構造をフラットなデータにする記事は検索すれば、たくさん出てきます。
しかし、フラットなデータをネストしたデータに変換するような記事はなかなか見当たりません。
今回はどのようにしてコードで実現するのかを、TypeScriptを使って考えてみようと思います。
成果物
https://github.com/kntks/blog-code/tree/main/2023/03/generate-nested-array
入力と求める出力
入力は深さと、名前を持ったオブジェクトの配列です。
入力データのルールは、
- 親は子よりも配列のインデックスが小さい
- 必ず木構造になる
[ { "depth": 2, name: "A" }, { "depth": 3, name: "AA" }, { "depth": 2, name: "B" }, { "depth": 3, name: "BB" }, { "depth": 4, name: "BBB" }, { "depth": 2, name: "C" }]イメージ図は以下の通りです。
求める結果は以下の通りです。
[ { {"depth": 2, name: "A" }, [ { "depth": 3, name: "AA" } ] }, { { "depth": 2, name: "B" }, [ { "depth": 3, name: "BB" }, [ { "depth": 4, name: "BBB" }, ] ] } { "depth": 2, name: "C" }]結論
type Depth = { depth: number;};
type NestedDepth = Depth | NestedDepth[];
function generateNestedArray(arr: Depth[]): NestedDepth[] { type DepthWithVisited = Depth & { visited: boolean };
const recursive = (arr: DepthWithVisited[], depth: number): NestedDepth[] => { const results: NestedDepth[] = []; for (let index = 0; index < arr.length; index++) { const current = arr[index]; if (current.visited) continue; if (current.depth < depth) break; if (current.depth === depth) { const { depth } = current; results.push({ depth }); current.visited = true; } if (current.depth > depth) results.push(recursive(arr.slice(index), depth + 1)); } return results; };
return recursive( arr.map((x) => ({ ...x, visited: false })), 2 );}実装
はじめにtypeを定義します。
TypeScript 3.7以降からRecursive Typeが使えるので、これを利用します。
type Depth = { depth: number;};
type NestedDepth = Depth | NestedDepth[];参考:
- (More) Recursive Type Aliases - TypeScript 3.7
- How to represent nested array with typescript - stackoverflow
generateNestedArrayの中を見てみる
実装のアイデアは深さ優先探索と同じです。
引数に渡された配列を上から順に見ていき、訪問済みかどうかを確認します。
function generateNestedArray(arr: Depth[]): NestedDepth[] { type DepthWithVisited = Depth & { visited: boolean };
// 第2引数のdepthは、関数実行中の基準となる深さになります。 const recursive = (arr: DepthWithVisited[], depth: number): NestedDepth[] => { const results: NestedDepth[] = []; for (let index = 0; index < arr.length; index++) { const current = arr[index];
// すでに訪問済みであるならば、配列を次に進める。 if (current.visited) continue;
// currrentの深さが、基準となる深さよりも小さい場合 // ループを終了して、結果を返す = 再帰関数を終了する = currentは兄弟でも、子でもない if (current.depth < depth) break;
// currentの深さが、基準となる深さと同じである場合、配列にpush // 訪問済みにする if (current.depth === depth) { const { depth } = current; results.push({ depth }); current.visited = true; }
// currentの深さが、基準となる深さよりも大きい場合、基準となる深さよりもまだ、子供がいることがわかる。 if (current.depth > depth) results.push(recursive(arr.slice(index), depth + 1)); } return results; };
return recursive( // 引数のデータに訪問フラグを追加して、再帰関数をスタートする arr.map((x) => ({ ...x, visited: false })), 2 );}テストを書いて動作確認してみる
実装が完了したので、実際にテストを書いて挙動が正しいか確認します。
import { generateNestedArray } from "../main";describe("", () => { test.each([ { name: "子のデータが1つネストしている", headings: [{ depth: 2 }, { depth: 3 }], expected: [{ depth: 2 }, [{ depth: 3 }]], }, { name: "孫に当たるデータは、子のデータにネストする", headings: [{ depth: 2 }, { depth: 3 }, { depth: 4 }], expected: [{ depth: 2 }, [{ depth: 3 }, [{ depth: 4 }]]], }, { name: "depthがすべて同じである場合、データはネストしない", headings: [{ depth: 2 }, { depth: 2 }, { depth: 2 }], expected: [{ depth: 2 }, { depth: 2 }, { depth: 2 }], }, { name: "子が2つある場合、ネストした配列に2つ入る", headings: [{ depth: 2 }, { depth: 3 }, { depth: 3 }], expected: [{ depth: 2 }, [{ depth: 3 }, { depth: 3 }]], }, ])("$name", ({ headings, expected }) => { expect(generateNestedArray(headings)).toEqual(expected); });});どうやら意図した挙動になっていそうです!
$ npm test
> generate-nested-array@1.0.0 test> jest --coverage --passWithNoTests
PASS src/__tests__/main.test.ts ✓ 子のデータが1つネストしている (1 ms) ✓ 孫に当たるデータは、子のデータにネストする ✓ depthがすべて同じである場合、データはネストしない (1 ms) ✓ 子が2つある場合、ネストした配列に2つ入る
----------|---------|----------|---------|---------|-------------------File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s----------|---------|----------|---------|---------|-------------------All files | 100 | 100 | 100 | 100 | main.ts | 100 | 100 | 100 | 100 |----------|---------|----------|---------|---------|-------------------Test Suites: 1 passed, 1 totalTests: 4 passed, 4 totalSnapshots: 0 totalTime: 0.26 s最後に
再帰関数を使うことで、ネストしたデータを作成できることがわかりました。しかし、挙動を把握するためにはしっかりコードを読む必要があります。個人的な意見ですが、もしforで実現できるのならば、再帰関数よりもfor文を選択した方が良いです。
参考になれば幸いです。