有条件地执行 for 循环 I 进行计数,并 Count downto In delphi

Conditionally executing a for loop I to count, and Count downto In delphi

提问人:user2708888 提问时间:11/17/2023 更新时间:11/18/2023 访问量:135

问:

我有一个函数,我向其中传递了一个布尔参数。我正在执行一些在两种情况下相同的代码,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.MathVcl.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 循环,它使您可以直接控制循环控制变量,因此您可以决定增加或减少它以及减少多少。