Visualize a tree: Difference between revisions

→‎JS Plain text: Updated the decorated-outline version with an option to prune out nodeless lines
m (→‎Python :: Functional composition: (edited a comment line))
(→‎JS Plain text: Updated the decorated-outline version with an option to prune out nodeless lines)
Line 1,297:
 
===Plain text===
====Decorated outline====
<lang JavaScript>(() => {
'use strict';
 
// drawTree :: Bool -> Tree String -> String
const main = () =>
const drawTree = blnCompact => tree => {
drawTree(dctTree);
// Simple decorated-outline style of ascii tree drawing,
// with nodeless lines pruned out if blnCompact is True.
const xs = draw(tree);
return unlines(
blnCompact ? (
xs.filter(
s => s.split('')
.some(c => !' │'.includes(c))
)
) : xs
);
};
 
// draw :: Tree String -> [String]
Line 1,331 ⟶ 1,344:
};
 
// TEST -----------------------------------------------
// drawTree :: Tree String -> String
const drawTreemain = tree() => {
unlinesconst tree = Node(draw(tree));
'Alpha', [
Node('Beta', [
Node('Epsilon', []),
Node('Zeta', []),
Node('Eta', [])
]),
Node('Gamma', [Node('Theta', [])]),
Node('Delta', [
Node('Iota', []),
Node('Kappa', []),
Node('Lambda', [])
])
]);
 
return [true, false]
 
.map(blnCompact => drawTree(blnCompact)(tree))
const dctTree = {
"type": "Node",.join('\n\n');
"root": "alpha",
"nest": [{
"type": "Node",
"root": "beta",
"nest": [{
"type": "Node",
"root": "gamma",
"nest": []
},
{
"type": "Node",
"root": "epsilon",
"nest": []
},
{
"type": "Node",
"root": "eta",
"nest": []
}
]
},
{
"type": "Node",
"root": "iota",
"nest": [{
"type": "Node",
"root": "kappa",
"nest": []
},
{
"type": "Node",
"root": "mu",
"nest": []
},
{
"type": "Node",
"root": "xi",
"nest": []
}
]
},
{
"type": "Node",
"root": "pi",
"nest": [{
"type": "Node",
"root": "rho",
"nest": []
},
{
"type": "Node",
"root": "tau",
"nest": []
},
{
"type": "Node",
"root": "phi",
"nest": []
}
]
},
{
"type": "Node",
"root": "psi",
"nest": []
}
]
};
 
// GENERIC FUNCTIONS ----------------------------
// GENERIC FUNCTIONS ----------------------------------
 
// Node :: a -> [Tree a] -> Tree a
const Node = (v, xs) => ({
type: 'Node',
root: v, // any type of value (consistent across tree)
nest: xs || []
});
 
// append (++) :: [a] -> [a] -> [a]
// append (++) :: String -> String -> String
const append = (xs, ys) => xs.concat(ys);
 
// chars :: String -> [Char]
const chars = s => s.split('');
 
// cons :: a -> [a] -> [a]
const cons = (x, xs) => [x].concat(xs);
Array.isArray(xs) ? (
[x].concat(xs)
) : (x + xs);
 
// Returns Infinity over objects without finite length.
// thisThis enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc
 
// length :: [a] -> Int
const length = xs => xs.length || Infinity;
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
 
// lines :: String -> [String]
Line 1,434 ⟶ 1,404:
length: n
}, () => x);
 
// shift :: Int -> [a] -> [a]
const shift = (n, xs) => {
const lng = length(xs);
return Infinity > lng ? (
take(lng, drop(n, cycle(xs)))
) : (drop(n, xs), xs);
};
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
xs.slice(0, n);
xs.constructor.constructor.name !== 'GeneratorFunction' ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
// unlines :: [String] -> String
Line 1,473 ⟶ 1,427:
 
// MAIN ---
const strTree =return main();
return (
// console.log(strTree),
strTree
);
})();</lang>
{{Out}}
<pre>alphaAlpha
├─ Beta
│ ├─ Epsilon
│ ├─ Zeta
│ └─ Eta
├─ Gamma
│ └─ Theta
└─ Delta
├─ Iota
├─ Kappa
└─ Lambda
 
Alpha
├─ betaBeta
│ │
│ ├─ gammaEpsilon
│ │
│ ├─ epsilonZeta
│ │
│ └─ etaEta
├─ iotaGamma
│ │
│ ├─ kappa
│ │
│ ├─ mu
│ │
│ └─ xi
├─ pi
│ │
│ ├─ rho
│ │
│ ├─ tau
│ │
│ └─ phiTheta
└─ psi</pre>Delta
├─ Iota
├─ Kappa
└─ Lambda</pre>
 
=={{header|Julia}}==
9,659

edits