打破嵌套循环

breaking a nested loop

我有一个嵌套循环,它正在检查 Wallet[] 中的任何 Currency 是否匹配 Currency[] UtilityTokens 中的任何 Currency。 在确定其中一个钱包确实包含实用程序令牌后,我想尽快打破我的嵌套循环继续前进。

我当前的代码如下:

bool walletContainsUtilityToken = false;
for(int i = 0; i < Wallets.Length; i++)
{
    foreach (Currency ut in ExchangeFunctions.UtilityTokens)
    {
        if (Wallets[i].Currency.Equals(ut))
        {
            walletContainsUtilityToken = true;
            break;
        }
    }
    if (walletContainsUtilityToken)
    {
        break;
    }
}

这是打破嵌套循环的合适方法吗? 有没有不同的、更有效的做事方式?

也许你可以使用 goto

示例:

            int val = 2;

            for(int i = 0; i <4;i++)    
            {
                for (int j =0;j<4; j++)
                {
                    if (val == i)
                        goto LoopsFinished;
                }

            }

            LoopsFinished:
                val = 0;

我们可以将其简化为 one-liner,它 执行您想要的提前退出:

bool walletContainsUtilityToken = Wallets.Any(w => ExchangeFunctions.UtilityTokens.Any( ut => ut == w.Currency));

这个可能更容易理解(没有嵌套,只有一个-shorter- lambda):

bool walletContainsUtilityToken = Wallets.Select(w => w.Currency).Intersect(ExchangeFunctions.UtilityTokens).Any();

选择第二个选项,为了清楚起见,我实际上是这样写的:

bool walletContainsUtilityToken = Wallets.
    Select(w => w.Currency).
    Intersect(ExchangeFunctions.UtilityTokens).
    Any();

如果您真的想继续使用完整循环,我会像这样对循环条件添加检查:

bool walletContainsUtilityToken = false;
for(int i = 0; i < Wallets.Length && !walletContainsUtilityToken; i++)
{
    foreach (Currency ut in ExchangeFunctions.UtilityTokens)
    {
        if (Wallets[i].Currency.Equals(ut))
        {
            walletContainsUtilityToken = true;
            break;
        }
    }
}

最后,如果这些列表很大,您可以通过 pre-arranging 将它们转化为数据结构以便更快地查找(即:字典,甚至支持二进制搜索的东西)来显着提高性能。但这只有在列表足够大的情况下才是胜利。

你的代码非常好,如果你想要 one-liner 这里有一个 Linq 替代方案。

bool walletContainsUtilityToken = Wallets.Any(w => ExchangeFunctions.UtilityTokens.Any(ut => w.Currency.Equals(ut)));