2010-04-06 54 views
0

我有一個場景,我想隨機顯示一些項目。給定一個父項,我如何隨機選擇其中的一個子項?如何從給定父節點的樹中獲取一個隨機項?

當然,我可以加載所有的孩子,並應用一些隨機索引或什麼...但這將是非常低效率。

我想知道如果這也是低效的:

Parent.Children [隨機(Parent.Children.Count)?

當您訪問Parent.Children時,哪些項目會被加載?

回答

2

Item.Children是一個懶加載的屬性,我絕對不建議完全按照您在這裏展示的方式使用它。

在發佈之前,我通過API進行了一些挖掘,看看是否真的沒有辦法在不加載此屬性的情況下獲得子項數,但是,我無法真正找到任何看起來似乎「合法」。只有.HasChildren屬性似乎涉及 - 似乎通過做大部分(但不是全部).Children屬性已經工作。

但是,由於它是延遲加載的,因此將該屬性的結果存儲在專用字段中以獲得最大效率。我記得有一次在官方的開發者指南中讀到了這一點,如果需要的話,我可以挖掘出確切的參考。

ChildList itemChildren = myItem.Parent.Children; 
// Continue doing random() etc here, but using the itemChildren field. 
+0

只是爲了澄清我的一些深夜打字... .Children屬性不是延遲加載,每次訪問時都會加載它。通常,懶惰加載意味着在第一次使用後緩存屬性值,但這不是這種情況。 – 2010-04-07 11:05:34

0

您是否擁有整個樹形結構?然後你可以做一些隨機遍歷。例如,您可以選擇從二叉樹像這樣(僞代碼)隨機項目:

sub randomNode(node): 
    randomVal = random(0, 3); // random value between 0 and 3 

    if(randomVal == 0): 
    return randomNode(node.left) if node.left != null else return node; 
    elseif(randomVal == 1): 
    return randomNode(node.right) if node.right != null else return node; 
    else 
    return node; 

對於n叉樹,你可以有這樣的事情:

sub randomNode(node): 
    randomVal = random(0, 2) 

    if(randomVal == 0): 
    return randomNode(node.children[random(0, node.children.length)]) if node.children.length != 0 else return node; 
    elseif(randomVal == 1): 
    return node; 

parent.children[random(parent.children.count)]對我來說似乎並不低效;這是我在上面的算法中使用的。至於你最後的問題,我想這取決於你如何實現你的樹。如果你自己建立了一個樹形結構,那麼你必須擁有整個樹形結構。如果你使用的是框架,那麼它取決於該框架的實現。

+0

感謝Vivin,但這是專門關於Sitecore API的。對不起,我沒有說清楚。 – Bryan 2010-04-06 20:57:20

+0

不用擔心!正如馬克所說,它看起來像這個領域得到延遲加載,所以沒有辦法告訴有多少孩子。我認爲按需加載不會以任何方式改變上述算法。 – 2010-04-06 21:18:59