递归函数返回false而不是true

时间:2019-11-13 10:29:11

标签: c# .net

private bool AnyChildDomainExists(Domain parentDomain, int childDomainID)
{
    if (parentDomain.DomainID == childDomainID)
        return true;

    foreach(Domain domain in parentDomain.Domains)
    {
        return AnyChildDomainExists(domain, childDomainID);
    }

    return false;
}

例如,这是我的树:

Root
  Child 1
     GrandChild 1
  Child 2
     GrandChild 2

我传入函数AnyChildDomainExists(root, GrandChild 2'sID),它返回false。该功能有一个小问题,但我无法弄清楚。

3 个答案:

答案 0 :(得分:4)

private bool AnyChildDomainExists(Domain parentDomain, int childDomainID)
{
    if (parentDomain.DomainID == childDomainID)
        return true;

    return parentDomain.Domains.Any(domain => AnyChildDomainExists(domain, childDomainID));

}

使用LINQ Any检查是否有任何子域ID匹配。

答案 1 :(得分:2)

另一种方法是仅在结果为@Html.EditorFor(x => x.PensionPayrollSchemeDesc, new { TabIndex = 1, id = "pension-payroll-schemes-list" }) $("#pension-payroll-schemes-list").on( "change", { url: "SelectedSchemeProcessingButtons", model: decodes }, onSchemeSelection); // Event handler for changing the selected scheme function onSchemeSelection(evt) { resetMessages(true); setProcessButtons(evt.data.url, false); } // Using the selected scheme, check the current status and set the buttons accordingly function setProcessButtons(actionUrl, refresh) { let scheme = $("#pension-payroll-schemes-list").val(); if (scheme === '') { setFileNetCaseRefState(); return; } let selection = $("#PensionPayrollSchemeNumber").val(); if (selection && selection > 0) { $('#processingModal').foundation('open'); setFileNetCaseRefState(selection); let suppressInfoMessage = refresh; return $.ajax({ url: actionUrl, data: antiforgeryModule.addAntiForgeryToken({ payrollSchemeNumber: selection, suppressInfoMessage: suppressInfoMessage }), type: 'POST', error: function (xhr, status, error) { $('#processingModal').foundation('close'); errorHandling.displayError(xhr, status, error, 'globalFormError'); errorHandling.clearSuccess('globalFormSuccess'); }, success: function (response) { $('#processingModal').foundation('close'); if (response) { $('#actionButtons').html(response); } setActions(); } }); } } // bind an action to the specified button click event function setAction(id, action, closeModal) { let button = $("#" + id); button.off("click").on("click", action, processAction); } // Set the process button actions function setActions() { setAction("doYearEnd", { url: YearEndJobAction, override: false, model: decodes, closeModal: false, next: function () { displaySuccess(YearEndSubmittedMessage); } }); } // Using the selected scheme, check the current status and set the buttons accordingly function setProcessButtons(actionUrl, refresh) { let scheme = $("#pension-payroll-schemes-list").val(); if (scheme === '') { setFileNetCaseRefState(); return; } let selection = $("#PensionPayrollSchemeNumber").val(); if (selection && selection > 0) { return $.ajax({ url: actionUrl, data: antiforgeryModule.addAntiForgeryToken({ payrollSchemeNumber: selection }), type: 'POST', error: function (xhr, status, error) { errorHandling.displayError(xhr, status, error, 'globalFormError'); errorHandling.clearSuccess('globalFormSuccess'); }, success: function (response) { if (response) { $('#actionButtons').html(response); } setActions(); } }); } } 时从内部循环返回。就目前而言,您将在子域的第一次迭代中返回一个值,这不是您想要的。

例如:

true

答案 2 :(得分:1)

编写循环的方式,它立即从第一个叶子节点返回结果,并将其一直传播到顶部。这意味着如果GrandChild 2返回false

解决此问题的一种方法是OR循环中所有子级的结果,例如:

private bool AnyChildDomainExists(Domain parentDomain, int childDomainID)
{
    if (parentDomain.DomainID == childDomainID)
        return true;

    bool result=false;
    foreach(Domain domain in parentDomain.Domains)
    {
        result|=AnyChildDomainExists(domain, childDomainID);
    }

    return result;
}

此代码将为节点22(GrandChild 2)返回true

    var tree=new Domain(0,new[]{
        new Domain(1,new[]{
            new Domain(11,new Domain[0])
        }),
        new Domain(2,new[]{
            new Domain(22,new Domain[0])
        })
    });

    var found=AnyChildDomainExists(tree,22);
    Debug.Assert(found);