【问题标题】:Break nested loop until next condition is meet中断嵌套循环,直到满足下一个条件
【发布时间】:2015-10-27 15:37:19
【问题描述】:

我有以下代码,我正在获取一个列表并将其平均分为三列:

<div>
    @{
        double num = listing.Count() / 3.0;
        double blockSize = Math.Ceiling(num);
        for (int i = 0; i < Math.Ceiling(listing.Count() / blockSize); i++)
        {

            <div class="col-sm-4">
                @for (int j = i * (int)blockSize; j < (i * blockSize) + (int)blockSize && j < listing.Count(); j++)
                {
                    /// How can I only display this header once?
                    foreach(string letter in letters)
                    {
                        if (letter.ToLower() == listing.ElementAt(j).Title.Substring(0,1).ToLower())
                        {    
                            <h5 class="title"><a name="@letter.ToLower()">@letter.ToUpper()</a></h5>
                        }
                    }


                    <p><a href="#">@listing.ElementAt(j).Value</a></p>

                }                                    
            </div>
        }                       
    }
</div>

我的问题是如何将嵌套的 foreach 循环编码为每个字母匹配只为真一次?产生如下输出:

<div class="row colIndentTop">
    <div class="col-sm-4">
        <h5 class="title"><a name="a">A</a></h5>
        <p><a href="#">Alice</a></p>
        <p><a href="#">Amy</a></p>


        <h5 class="title"><a name="d">D</a></h5>
        <p><a href="#">David</a></p>

        <h5 class="title"><a name="f">F</a></h5>
        <p><a href="#">Frank</a></p>

        <h5 class="title"><a name="i">I</a></h5>
        <p><a href="#">Ibrahim</a></p>
    </div>
    <div class="col-sm-4">
        <h5 class="title"><a name="n">N</a></h5>
        <p><a href="#">Nancy</a></p>

        <h5 class="title"><a name="o">O</a></h5>
        <p><a href="#">Olive</a></p>

        <h5 class="title"><a name="p">P</a></h5>
        <p><a href="#">Paul</a></p>                        
        <p><a href="#">Patrick</a></p>
    </div>
    <div class="col-sm-4">
        <p><a href="#">Patricia</a></p>

        <h5 class="title"><a name="s">S</a></h5>
        <p><a href="#">Sally</a></p>
        <p><a href="#">Sean</a></p>

        <h5 class="title"><a name="t">T</a></h5>
        <p><a href="#">Thomas</a></p>
    </div>
</div>

而不是:

<div class="row colIndentTop">
    <div class="col-sm-4">
        <h5 class="title"><a name="a">A</a></h5>
        <p><a href="#">Alice</a></p>
        <h5 class="title"><a name="a">A</a></h5>
        <p><a href="#">Amy</a></p>


        <h5 class="title"><a name="d">D</a></h5>
        <p><a href="#">David</a></p>

        <h5 class="title"><a name="f">F</a></h5>
        <p><a href="#">Frank</a></p>

        <h5 class="title"><a name="i">I</a></h5>
        <p><a href="#">Ibrahim</a></p>
    </div>
    <div class="col-sm-4">
        <h5 class="title"><a name="n">N</a></h5>
        <p><a href="#">Nancy</a></p>

        <h5 class="title"><a name="o">O</a></h5>
        <p><a href="#">Olive</a></p>

        <h5 class="title"><a name="p">P</a></h5>
        <p><a href="#">Paul</a></p>   
        <h5 class="title"><a name="p">P</a></h5>                     
        <p><a href="#">Patrick</a></p>
    </div>
    <div class="col-sm-4">
        <h5 class="title"><a name="p">P</a></h5>
        <p><a href="#">Patricia</a></p>

        <h5 class="title"><a name="s">S</a></h5>
        <p><a href="#">Sally</a></p>
        <h5 class="title"><a name="s">S</a></h5>
        <p><a href="#">Sean</a></p>

        <h5 class="title"><a name="t">T</a></h5>
        <p><a href="#">Thomas</a></p>
    </div>
</div>

提前致谢!

【问题讨论】:

    标签: c# asp.net-mvc for-loop foreach


    【解决方案1】:

    嗯。您拥有的整个代码可能有更优雅的解决方案,但对于您的具体问题,您可以添加一个简单的检查。

    此代码会将字母值添加到变量 thisLetter 并检查下一个 foreach 以确保您的字母是新的(否则 letter != thisLetter 将失败并跳过添加 h5)

    var thisLetter = '';
    
    foreach(string letter in letters)
    {
        if ((letter.ToLower() == listing.ElementAt(j).Title.Substring(0,1).ToLower()) && letter != thisLetter)
        {    
            <h5 class="title"><a name="@letter.ToLower()">@letter.ToUpper()</a></h5>
        }
        thisLetter = letter;
    }
    

    您也可以使用 continue 逻辑进行如下清理,这不会创建 h5 并且还会跳过对 thisLetter 的不必要的重新分配。作为解释,continue 将跳到 for 循环的下一次迭代,而不执行循环中 continue 之后的任何代码。

    var thisLetter = '';
    
    foreach(string letter in letters)
    {
        //Note!: The if logic is 'opposite' in this structure.
        if ((letter.ToLower() != listing.ElementAt(j).Title.Substring(0,1).ToLower()) || letter == thisLetter)
            continue;
    
        <h5 class="title"><a name="@letter.ToLower()">@letter.ToUpper()</a></h5>
        thisLetter = letter;
    }
    

    【讨论】:

    • 这与现有代码完美配合,感谢您提供多种解决方案!
    • 没问题!祝你好运。
    【解决方案2】:

    首先按字母对您的姓名(indexNavigation)进行排序。那就这样吧(可能编译不出来,我现在没有IDE):

    <div>
        @{
            double num = listing.Count() / 3.0;
            double blockSize = Math.Ceiling(num);
            char currentLetter = '.'
            for (int i = 0; i < Math.Ceiling(listing.Count() / blockSize); i++)
            {
    
                <div class="col-sm-4">
                    @for (int j = i * (int)blockSize; j < (i * blockSize) + (int)blockSize && j < listing.Count(); j++)
                    {
                        var name = indexNavigation.ElementAt(j).Title;
                        if (currentLetter != name.Title.Substring(0,1).ToLower()[0])
                        {    
                            <h5 class="title"><a name="@letter.ToLower()">@letter.ToUpper()</a></h5>
                            currentLetter = name.Title.Substring(0,1).ToLower()[0];
                        }
    
                        <p><a href="Faculty_and_Research/Academic_Careers.html">@indexNavigation.ElementAt(j).Title</a></p>    
                    }                                    
                </div>
            }                       
        }
    </div>
    

    【讨论】:

    • 虽然我最终使用了其他解决方案,但我想对您的答案进行投票,并且它确实有效。感谢您的回复!
    猜你喜欢
    • 2022-11-23
    • 2021-12-24
    • 2021-08-10
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 2016-04-12
    • 2018-06-29
    相关资源
    最近更新 更多