提问人:user2708888 提问时间:11/17/2023 更新时间:11/18/2023 访问量:135
有条件地执行 for 循环 I 进行计数,并 Count downto In delphi
Conditionally executing a for loop I to count, and Count downto In delphi
问:
我有一个函数,我向其中传递了一个布尔参数。我正在执行一些在两种情况下相同的代码,boolean 参数将仅确定循环的方向,如下所示:
If True then
begin
for I:= 0 to Count do
begin
Execute a chunk of code
end;
end
else
begin
for Count downto 0 do
begin
Execute same chunk of code
end;
end;
我怎样才能比复制要在循环中执行的代码块更优雅地编写它?
我是尝试编程的新手,所以对我放轻松,并为我的术语道歉
我尝试过搜索,但我的术语或解释方式都关闭了,因为我找不到类似的帮助文章。
答:
2赞
Ken White
11/17/2023
#1
可以通过将代码移动到调用的单独函数/过程中,传入循环计数器的值来防止重复代码。
procedure ExecuteAChunkOfCode(const Index: Integer);
begin
// Your chunk of code here
end;
procedure DoCountedOperation(const CountUp: Boolean);
var
i: Integer;
begin
if CountUp then
begin
for i := 0 to Count do
ExecuteAChunkOfCode(i);
end else
begin
for i := Count downto 0 do
ExecuteChunkOfCode(i);
end;
end;
// Forward loop
DoCountedOperation(True);
// Backward loop
DoCountedOperation(False);
评论
1赞
Remy Lebeau
11/17/2023
你可以更进一步,使它成为一个本地函数或一个匿名过程ExecuteChunkOfCode
0赞
Ken White
11/17/2023
@RemyLebeau:你也可以这样做。我不知道 OP 使用的是哪个版本的 Delphi。:-)感谢您修复我代码中的愚蠢错别字。
1赞
David Heffernan
11/17/2023
你绝对可以避免有两个循环,你只需要做一些数学运算
1赞
Ken White
11/18/2023
@DavidHeffernan:你说得对。我的措辞有误。我已经纠正了它。谢谢。
-1赞
Remy Lebeau
11/17/2023
#2
只需使用 1 个循环并使用一个单独的变量来保存“循环计数器”,该计数器根据所需的“方向”递增或递减,例如:
var
I, Counter: Integer;
begin
if BoolParam then Counter := 0
else Counter := Count;
for I := 0 to Count do
begin
// Execute a chunk of code
// using Counter as needed...
if BoolParam then Inc(Counter)
else Dec(Counter);
end;
end;
或者:
function iif(const ACondition: Boolean;
const AIfTrue, AIfFalse: Integer): Integer; inline;
begin
if ACondition then Result := AIfTrue
else Result := AIfFalse;
end;
var
I, Counter, NumToAdd: Integer;
begin
Counter := iif(BoolParam, 0, Count);
NumToAdd := iif(BoolParam, 1, -1);
for I := 0 to Count do
begin
// Execute a chunk of code
// using Counter as needed...
Inc(Counter, NumToAdd);
end;
end;
评论
0赞
Matej
11/17/2023
您无需定义自己的 iif 函数。这已经作为 System.Math 单元中的 IfThen 函数存在,请参阅 docwiki.embarcadero.com/Libraries/Alexandria/en/...
1赞
Remy Lebeau
11/18/2023
@Matej 没错,但也是一个巨大的单位,仅仅为了 1 个功能而将其拉入是矫枉过正的。System.Math
0赞
David Heffernan
11/18/2023
真?你是怎么确定这是整个程序中唯一使用数学单元的函数的?那么如果单位很大怎么办。缺点是什么?
1赞
Remy Lebeau
11/18/2023
@DavidHeffernan我没有,但不是每个程序都使用(我写的很少)。缺点是不必要的 exe 膨胀。例如,出于这个原因,许多人倾向于避免在不需要 UI 功能的控制台应用中包含内容。System.Math
Vcl.Application
0赞
SilverWarior
11/17/2023
#3
您可以通过从循环大小中减去 I 控制值来反转循环。下面是一个示例:
var OffsetItem: Integer;
for I:= 0 to Count do
begin
//Normal loop
if true then OffsetIndex := I
//Reverse loop
end else OffsetIndex := Count-I;
//Execute a chunk of code using OffsetIndex instead of I;
end;
或者,您可以使用 while 循环,它使您可以直接控制循环控制变量,因此您可以决定增加或减少它以及减少多少。
评论