[topic] 親子のペアからツリーを構築
Posted feedbacks - JavaScript
JavaScript でプロパティでツリーを表現してみました。
実行例:
add("A", "B");
add("B", "C");
add("C", "D");
add("C", "E");
add("A", "F");
add("D", "X");
add("Y", "Z");
add("Z", "C");
print(family_toString(family));
/* 出力 */
A
->F
->B
->C
->D
->X
->E
Y
->Z
->C
->D
->X
->E
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | var cache = {};
var family = {};
function add(parent, child){
var p,c;
if(parent in cache){
p = cache[parent];
} else { //初めての名前
p = family[parent] = { name : parent };
cache[parent] = p;
}
if(child in cache){
p[child] = cache[child];
} else { //初めての名前
c = p[child] = { name : child };
cache[child] = c;
}
}
family_toString.tab = " ";
function family_toString(f, tab){
var result = "";
if(tab == null) tab = -1;
var indent = arguments.callee.tab.x(tab);
for( x in f){
if(x == "name") continue;
else{
result += indent + (tab < 0 ? "" : "->") + f[x].name + "\n";
result += family_toString(f[x], tab+1);
}
}
return result;
}
if(!String.prototype.x){
String.prototype.x = function(n){
var result="", i;
for(i=0;i<n;i++){
result += this;
}
return result;
}
}
|
既存の子を追加する時、 親がいなかったノードが後から親を指定された時ルート参照を削除した方がよい
1 2 3 | if(child in family){
delete family[child];
}
|





hu2 #6327() [ Common Lisp ] Rating0/0=0.00
親子ペア定義群からツリー構造をつくります ・親子ペア定義 ※親->子 A->B B->C C->D C->E A->F D->X Y->Z Z->C ・ツリー A ->B ->C ->D ->X ->E ->F Y ->Z ->C ->D ->X ->E; 親子ペア定義 (setf pair-lst '((a b) (b c) (c d) (c e) (a f) (d x) (y z) (z c) )) ;; 同一の親を持つペアをマージする ;; ex) ((p1 c1) (p1 c2) (p2 c3) (p2 c4)) -> ((p1 c1 c2) (p2 c3 c4)) (defun gen-fmly-lst (plst) (defun merge-lst (frst rst) (if (null rst) frst (if (eq (car frst) (caar rst)) (merge-lst (append frst (cdar rst)) (cdr rst)) (merge-lst frst (cdr rst))))) (labels ((rec (lst acc) (if (null lst) acc (if (member (caar lst) acc :key #'car) (rec (cdr lst) acc) (rec (cdr lst) (cons (merge-lst (car lst) (cdr lst)) acc)))))) (rec plst nil))) ;; fmlyのリストからツリーを生成する (defun gen-fmly-tr (fmly-lst) (labels ((rec (flst acc) (if (null flst) acc ; hook前のfmlyをhook後のfmly(n次元リスト)に置き換えて処理をする (let* ((nD-fmly (car (member (caar flst) acc :key #'car))) (othr (other nD-fmly acc))) ; fmlyをhook処理し、一箇所もhookできなかったらfmlyをそのままaccに加える (if (equal othr (hook nD-fmly othr)) (rec (cdr flst) (cons nD-fmly othr)) (rec (cdr flst) (hook nD-fmly othr))))))) (rec fmly-lst fmly-lst))) ;; リストからobjを除いたリストを取得する (defmacro other (obj lst) `(remove-if #'(lambda (x) (equal ,obj x)) ,lst)) ;; リストのcarと一致するatomをツリーの中で見つけた場合、該当atomをリストで置き換える ;; ex) (hook '(a x) '(a (b a) (c (d a)))) -> ((a x) (b (a x)) (c (d (a x)))) (defun hook (lst tree) (cond ((eq (car lst) tree) lst) ((atom tree) tree) (t (cons (hook lst (car tree)) (hook lst (cdr tree)))))) (defun main () (gen-fmly-tr (gen-fmly-lst pair-lst))) ; 実行すると、下記の構造が得られる ; ((A (B (C (D X) E)) F) (Y (Z (C (D X) E)))) ; インデントすると ;((A ; (B ; (C ; (D ; X) ; E)) ; F) ; (Y ; (Z ; (C ; (D ; X) ; E))) ; )Rating0/0=0.00-0+
[ reply ]