私は Node.js を使用しており、Mongoose を介して MongoDB からの値を階層リストに入力する Dust.js テンプレートを使用しています。テンプレートに到達する前にデータをフィルタリングしようとすることは明らかに理想的ですが、これを行う方法を理解するのに役立つものはほとんど見つからなかったので、jQuery を介してクライアント側で行っています。このコードは深刻なハッカーです。ご容赦ください。しかし、少なくともマージの最初のレベルでは機能します。
私の Mongoose データは、カテゴリとサブカテゴリに配置されたカード デッキのドリル ダウン、階層メニュー (HTML の単純な ul li タイプ リスト構造) を生成します。すべてのデッキにサブカテゴリがあるわけではなく、同じ数のサブカテゴリがあるわけでもありません。ここでは noSQL のアイデアを真に受け入れているので、これらは各デッキに組み込まれています。しかし、MySQL から来ているので、これを Mongoose で調整するのは簡単ではありません。
カテゴリとサブカテゴリは各デッキの JSON に埋め込まれているため、すべてのカテゴリをマージし、次にサブカテゴリ 1 を 1 つずつマージして、デッキのデータにすばやく移動するための適切な場所にデッキを配置する必要があります。
私が今日書いたコード (私が言ったように、かなり恐ろしいことです!) は、リストのトップレベルをマージします。このコードを実行すると、重複のあるトップ レベルのカテゴリがマージされ、すべての子が保持されます。
私の質問: このコードを大幅に改善したいと思います。現在、私は 4 つか 5 つのレベルごとにこのような関数を作成することを検討しています。これにより、私が制限されたくない方法で制限されます (被験者が本当に 6 つのレベルを必要とする場合はどうなるでしょうか?) 具体的には、私は'好きです:
次のレベルに重複するサブジェクトがあるかどうかを再帰的に確認する、子を含むリストの一部をマージする方法。
代わりに最下位レベルからマージを開始するのが賢明でしょうか?
先ほど言ったように、これはテンプレートがレンダリングされる前にデータをフィルタリングすることでおそらくうまくいくでしょうが、私はまだそれを考えようとはしていません.
これが私のコードです:
function mergeLevel1() {
var count = 0;
var subcatText;
var subcatTextCurrent;
$.each($("ul.rootlist > li").not("ul li ul a"), function() {
var firstNode = $(this)
var nodeText = $("a:first", this).text();
//toastr.warning('nodeText is ' + nodeText)
$.each($("ul.rootlist > li").not("ul li ul a").not(firstNode), function() {
var siblingNode = $(this)
var siblingText = $("a:first", this).text();
//toastr.info('running sibling, siblingText is ' + siblingText)
if (nodeText == siblingText) {
toastr.info('i found a duplicate for ' + siblingText)
siblingNode.children().find('li').each(function(){
if (count == 0) {
subcatText = $(this).text();
}
subcatTextCurrent = $(this).text();
count++
toastr.warning("found children of a duplicate " + $(this).text())
//var targetNode = $("a:first", theNode).text()
toastr.info('try appending to ' + '#'+siblingText+'_ul'+'_'+subcatText)
if (count > 1) {
toastr.error('moving node!')
$(this).appendTo('#'+siblingText+'_ul_'+subcatText);
}
})
}
});
removeEmpties();
});
// end merge level 1
}
function removeEmpties() {
$('ul:empty').parent().remove();
}