1
votes

In Ada, how do you loop across any array by any index, starting after the first index? By "any array", we mean empty arrays and arrays whose index is not an integer, too.

EDIT: If an initial conditional is required to handle corner cases - for example: empty arrays - that is fine.

EDIT: Specified "any index" instead of just the second.

2
After following the comments to @Jere’s answer, I find that I don’t understand what it is that you’re trying to do. "I can do this in C, how can I do it in Ada?" would help a lot. - Simon Wright

2 Answers

6
votes

Remember that the Ada 'for' loop does not include an increment operator. Instead it iterates through a range of values. The range of values may be the entire set of array indices or it may be a contiguous subset of that range. The easiest way to accomplish this is to declare an unconstrained array type and then pass the slice of the array you want to process.

procedure main is    
     type Days is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
     type Day_Counts is array(Days range <>) of Integer;
     function Total(Item : in Day_Counts) return Integer is
        Sum : Integer := 0;
     begin
        for Day in Item'Range loop
            Sum := Sum + Item(Day);
        end loop;
        return Sum;
     end Total;

     Weekly_Counts : DayCounts := (1,2,3,4,5,6,7);
     Weekly_Sum : Integer;
     Weekend_Sum : Integer;
  begin
    Weekly_Sum := Total(Weekly_Counts);
    Weekend_Sum := Total(Weekly_Counts(Sat..Sun));
  end main;

The value placed in Weekly_Sum will be the sum of all 7 array elements. The value placed in Weekend_Sum will be the sum of only the Sat and Sun values.

4
votes

In Ada you can specify which indexes to iterate over:

-- Declarations
Start  : Index_Type;
Finish : Index_Type;
-- Usage
Start := -- Pick your start
Finish := -- Pick your end
for Index in Start .. Finish loop
   -- do your stuff
end loop;

-- Example
with Ada.Text_IO; use Ada.Text_IO;

procedure Test is

    type Index_Type is (Red, Blue, Green);
    type Array_Type is array(Index_Type range <>) of Integer;

    My_Array : Array_Type(Index_Type'Range) := (1,2,3);

    Start, Finish : Index_Type;

begin

    Start  := Blue;
    Finish := Green;

    for Index in Start .. Finish loop
       Put_Line(My_Array(Index)'Image); 
    end loop;

    Put_Line("Hello World");

end Test;

where Start and End can be any index type you want. Or you can just iterate over all of them if you want and let the compiler determine what the first and last are.

This works for any type that can be an index of an array (Enumerations, Integers, etc.).

For any index type you can do things like:

Index_Type'First
Index_Type'Last
Index_Type'Succ(value)
Index_Type'Pred(value)
My_Array'Length
My_Array'Range

among many others. These should allow you to do what index math you need (again independent of the index type). See some examples below

for Index in My_Array'Range loop
   if Index /= My_Array'First then
      -- do stuff here
   end if;
end loop;

if My_Array'First /= Index_Type'Last then
   for Index in Index_Type'Succ(My_Array'First) .. My_Array'Last loop
      -- Do your stuff
   end loop;
end if;