打破嵌套循环
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)));
我有一个嵌套循环,它正在检查 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)));