Loop over multiple arrays simultaneously

Revision as of 21:04, 17 July 2010 by 24.41.5.170 (talk) (changed lang tag for Clojure)

Loop over multiple arrays (or lists or tuples or whatever they're called in your language) and print the ith element of each. Use your language's "for each" loop if it has one, otherwise iterate through the collection in order with some other loop.

Task
Loop over multiple arrays simultaneously
You are encouraged to solve this task according to the task description, using any language you may know.

For this example, loop over the arrays (a,b,c), (A,B,C) and (1,2,3) to produce the output

aA1
bB2
cC3

If possible, also describe what happens when the arrays are of different lengths.

Ada

<lang Ada>with Ada.Text_IO; use Ada.Text_IO;

procedure Array_Loop_Test is

  type Array_Index is range 1..3;
  A1 : array (Array_Index) of Character := "abc";
  A2 : array (Array_Index) of Character := "ABC";
  A3 : array (Array_Index) of Integer   := (1, 2, 3);

begin

  for Index in Array_Index'Range loop
     Put_Line (A1 (Index) & A2 (Index) & Integer'Image (A3 (Index))(2));
  end loop;

end Array_Loop_Test;</lang>

AutoHotkey

<lang autohotkey>List1 = a,b,c List2 = A,B,C List3 = 1,2,3 MsgBox, % LoopMultiArrays()

List1 = a,b,c,d,e List2 = A,B,C,D List3 = 1,2,3 MsgBox, % LoopMultiArrays()


---------------------------------------------------------------------------

LoopMultiArrays() { ; print the ith element of each

---------------------------------------------------------------------------
   local Result
   StringSplit, List1_, List1, `,
   StringSplit, List2_, List2, `,
   StringSplit, List3_, List3, `,
   Loop, % List1_0
       Result .= List1_%A_Index% List2_%A_Index% List3_%A_Index% "`n"
   Return, Result

}</lang> An array that is too short on creation will return empty strings when trying to retrieve further elements. The 2nd Message box shows:

aA1
bB2
cC3
dD
e

C

Implemented to print from a list of lists. <lang c>#include <stdio.h>

typedef struct closure {

   void (*f)( void *elem, void *data);
   void  *data;

} *Closure;

typedef struct listSpec{

   void (*print)( void *);
   void *ary;
   int  count;
   short elem_size;

} *ListSpec;

  1. define LIST_SPEC( pf,typ,aa) {pf, aa, (sizeof(aa)/sizeof(typ)), sizeof(typ) }


/* calls closure's function f for each element in list */ void DoForEach( Closure c, ListSpec aspec ) {

   int i;
   void *val_ptr;
   for (i=0, val_ptr=aspec->ary; i< aspec->count; i++) {
       (*c->f)(val_ptr, c->data);
        val_ptr = ((char *)val_ptr) + aspec->elem_size;
   }

}

/* Used to find the minimum array length of list of lists */ void FindMin( ListSpec *paspec, int *minCount ) {

   ListSpec aspec = *paspec;
   if (*minCount>aspec->count) *minCount = aspec->count;

}

/* prints an element of a list using the list's print function */ void PrintElement( ListSpec *paspec, int *indx ) {

   ListSpec aspec = *paspec;
   (*aspec->print)( ((char*)aspec->ary) + (*indx)*aspec->elem_size);

}


/* Loop Over multiple lists (a list of lists)*/ void LoopMultiple( ListSpec arrays) {

   int indx;
   int minCount = 100000;
   struct closure c1 = { &FindMin, &minCount };
   struct closure xclsr = { &PrintElement, &indx };
   DoForEach( &c1, arrays);
   printf("min count = %d\n", minCount);
   for (indx=0; indx<minCount; indx++) {
       DoForEach(&xclsr, arrays );
       printf("\n");
   }

}

/* Defining our Lists */

void PrintInt( int *ival) { printf("%3d,", *ival); } int ary1[] = { 6,5,4,9,8,7 }; struct listSpec lspec1 = LIST_SPEC( &PrintInt, int, ary1 );

void PrintShort( short *ival) { printf("%3d,", *ival); } short ary2[] = { 3, 66, 20, 15, 7, 22, 10 }; struct listSpec lspec2 = LIST_SPEC( &PrintShort , short, ary2 );

void PrintStrg( char **strg ) { printf(" %s", *strg); } char *ary3[] = {"Hello", "all", "you","good", "folks","out", "there" }; struct listSpec lspec3 = LIST_SPEC( &PrintStrg , char *, ary3 );

void PrintLstSpec( ListSpec *ls ) { printf("not-implemented"); } ListSpec listList[] = { &lspec1, &lspec2, &lspec3 }; struct listSpec llSpec = LIST_SPEC(&PrintLstSpec, ListSpec, listList);

int main(int argc, char *argv[]) {

   LoopMultiple( &llSpec);
   return 0;

}</lang>

  1. include <iostream>
  2. include <vector>

C++

With std::vectors: <lang cpp>#include <iostream>

  1. include <vector>

int main(int argc, char* argv[]) {

  std::vector<char> ls(3); ls[0] = 'a'; ls[1] = 'b'; ls[2] = 'c';
  std::vector<char> us(3); us[0] = 'A'; us[1] = 'B'; us[2] = 'C';
  std::vector<int> ns(3);  ns[0] = 1;   ns[1] = 2;   ns[2] = 3;
  std::vector<char>::const_iterator lIt = ls.begin();
  std::vector<char>::const_iterator uIt = us.begin();
  std::vector<int>::const_iterator nIt = ns.begin();
  for(; lIt != ls.end() && uIt != us.end() && nIt != ns.end();
      ++lIt, ++uIt, ++nIt)
  {
     std::cout << *lIt << *uIt << *nIt << "\n";
  }

}</lang>

Using static arrays: <lang cpp>#include <iostream>

int main(int argc, char* argv[]) {

  char ls[] = {'a', 'b', 'c'};
  char us[] = {'A', 'B', 'C'};
  int ns[] = {1, 2, 3};
  for(size_t li = 0, ui = 0, ni = 0;
      li < sizeof(ls) && ui < sizeof(us) && ni < sizeof(ns) / sizeof(int);
      ++li, ++ui, ++ni)
  {
     std::cout << ls[li] << us[ui] << ns[ni] << "\n";
  }

}</lang>

C#

<lang csharp> class Program

   {
       static void Main(string[] args)
       {
           char[] a = { 'a', 'b', 'c' };
           char[] b = { 'A', 'B', 'C' };
           int[] c = { 1, 2, 3 };
           int min = Math.Min(a.Length, b.Length);
           min = Math.Min(min, c.Length);
           for (int i = 0; i < min; i++)
           {
               Console.WriteLine("{0}{1}{2}", a[i], b[i], c[i]);
           }
                      
           Console.ReadLine();
       }             
   }</lang>

Clojure

<lang clojure>(doseq [s (map #(str %1 %2 %3) "abc" "ABC" "123")]

 (println s))</lang>

The sequence stops when the shortest list is exhausted.

Common Lisp

<lang lisp>(mapc (lambda (&rest args)

       (format t "~{~A~}~%" args))
     '(|a| |b| |c|)
     '(a b c)
     '(1 2 3))</lang>

If lists are different lengths, it stops after the shortest one.

D

This code snippet will clamp to the array of the shortest length <lang d>char[]arr1 = "abc",arr2 = "ABC"; int[]arr3 = [1,2,3]; foreach(i,ele;arr1) {

 if (i == arr2.length || i == arr3.length) {
   break;
 }
 std.writefln("%s",""~ele~arr2[i]~std.string.toString(arr3[i]));

}</lang>

E

E lacks a nice way to do this; this is to be fixed, once we figure out what to do. However, iteration over an List produces its indexes as keys, so a not entirely awful idiom exists:

<lang e>def a1 := ["a","b","c"] def a2 := ["A","B","C"] def a3 := ["1","2","3"]

for i => v1 in a1 {

   println(v1, a2[i], a3[i])

}</lang>

This will obviously fail if a2 or a3 are shorter than a1, and omit items if a2 or a3 are longer.

Given a parallel iteration utility, we might write this:

<lang e>for [v1, v2, v3] in zip(a1, a2, a3) {

   println(v1, v2, v3)

}</lang>

zip cannot yet be defined for all collections (other than by iterating over each one and storing the results in a List first); but we can define it for numeric-indexed collections such as Lists, as below. Both a definition for any number of collections and two collections is given; the latter in order to demonstrate the principle without the clutter resulting from handling a variable number of collections.

<lang e>def zip {

 to run(l1, l2) {
   def zipped {
     to iterate(f) {
       for i in int >= 0 {
         f(i, [l1.fetch(i, fn { return }),
               l2.fetch(i, fn { return })])
       }
     }
   }
   return zipped
 }
 match [`run`, lists] {
   def zipped {
     to iterate(f) {
       for i in int >= 0 {
         var tuple := []
         for l in lists {
           tuple with= l.fetch(i, fn { return })
         }
         f(i, tuple)
       }
     }
   }
   zipped
 }

}</lang>

(This will stop when the end of the shortest collection is reached.)

Efene

<lang efene>@public run = fn () {

   lists.foreach(fn ((A, B, C)) { io.format("~s~n", A, B, C) }, lists.zip3("abc", "ABC", "123"))

} </lang>

If the lists are not all the same length, an error is thrown.

Erlang

Shortest option: <lang erlang>lists:zipwith3(fun(A,B,C)-> io:format("~s~n",A,B,C) end, "abc", "ABC", "123").</lang> However, as every expression in Erlang has to return something, printing text returns 'ok'. A list with as many 'ok's as there are lines printed will thus be created. The technically cleanest way to do things would be with lists:foreach/2, which also guarantees evaluation order: <lang erlang>lists:foreach(fun({A,B,C}) -> io:format("~s~n",A,B,C) end,

             lists:zip3("abc", "ABC", "123")).</lang>

If the lists are not all the same length, an error is thrown.

Factor

<lang factor>"abc" "ABC" "123" [ [ write1 ] tri@ nl ] 3each</lang>

Forth

<lang forth>create a char a , char b , char c , create b char A , char B , char C , create c char 1 , char 2 , char 3 ,

main
 3 0 do cr
   a i cells + @ emit
   b i cells + @ emit
   c i cells + @ emit
 loop
 cr
 a b c
 3 0 do cr
   3 0 do
     rot dup @ emit cell+
   loop
 loop
 drop drop drop
</lang>

Haskell

<lang haskell>main = mapM_ putStrLn $ zipWith3 (\a b c -> [a,b,c]) "abc" "ABC" "123"</lang> zipWith (2 lists) and zipWith3 are exported by Prelude. zipWith4 through zipWith7 are available in the Data.List module.

If lists are different lengths, it stops after the shortest one.

HaXe

<lang HaXe>package;

import neko.Lib;

using Lambda; using Std;

class Main {

static function main() { var a = ['a', 'b', 'c']; var b = ['A', 'B', 'C']; var c = [1, 2, 3];

//Find smallest array var len = [a, b, c] .map(function(a) return a.length) .fold(Math.min, 0x0FFFFFFF) .int();

for (i in 0...len) Lib.println(a[i] + b[i] + c[i].string()); } }</lang>

HicEst

<lang HicEst>CHARACTER :: A = "abc" REAL :: C(3)

C = $ ! 1, 2, 3

DO i = 1, 3

  WRITE() A(i), "ABC"(i), C(i)

ENDDO</lang>

Icon and Unicon

Icon

<lang Icon>link numbers # for max

procedure main()

a := ["a","b","c"] b := ["A","B","C","D"] c := [1,2,3]

every i := 1 to max(*a,*b,*c) do

  write(a[i]|"","\t",b[i]|"","\t",c[i]|"")

end</lang> The solution handles unequal list lengths.

numbers provides max

Unicon

This Icon solution works in Unicon.


J

For arrays of different types: <lang J>,.&:(":"0@>)/ 'abc' ; 'ABC' ; 1 2 3</lang> This approach works by representing the digits as characters.

Where arrays are all the same type (all numeric or all string): <lang J>,.&:>/ 'abc' ; 'ABC' ; '123'</lang>

Both of these implementations reject arrays with conflicting lengths.

Other options include:

<lang J>|: 'abc', 'ABC' ,:;":&> 1 2 3</lang> <lang J>|: 'abc', 'ABC',: '123'</lang> These implementations pad short arrays with spaces.

Or:

<lang J>|:>]&.>L:_1 'abc';'ABC';<1 2 3</lang>

This implementation puts each item from each of the original lists into a box and forms an array of boxes. (A "box" is a immutable pointer to immutable data -- in other words value semantics instead of reference semantics -- and "putting an item into a box" is obtaining one of these pointers for that item.) This implementation extends any short array by providing empty boxes to represent the missing elements.

Java

Translation of: JavaScript

<lang java>String[] a = {"a","b","c"}; String[] b = {"A","B","C"}; int[] c = {1,2,3}; for (int i = 0;i < a.length;i++) {

   System.out.println(a[i] + b[i] + c[i] + "\n");

}</lang> If one array is too "short", an ArrayIndexOutOfBoundException will be thrown.

JavaScript

This loops over the indices of the first array, and uses that to index into the others. <lang javascript>var a = ["a","b","c"]; var b = ["A","B","C"]; var c = [1,2,3]; var output = ""; for (var i in a) {

   output += a[i] + b[i] + c[i] + "\n";

}</lang> If one array is too "short", you will see the string "undefined" appear in the output.

Liberty BASIC

<lang lb>a$(1)="a" : a$(2)="b" : a$(3)="c" b$(1)="A" : b$(2)="B" : b$(3)="C" c(1)=1 : c(2)=2 : c(3)=3


for i = 1 to 3

   print a$(i);b$(i);c(i)

next</lang>

Lisaac

<lang Lisaac>Section Header

+ name := ARRAY_LOOP_TEST;

Section Public

- main <- (

 + a1, a2 : ARRAY[CHARACTER];
 + a3 : ARRAY[INTEGER];
 a1 := ARRAY[CHARACTER].create 1 to 3;
 a2 := ARRAY[CHARACTER].create 1 to 3;
 a3 := ARRAY[INTEGER].create 1 to 3;
 1.to 3 do { i : INTEGER;
   a1.put ((i - 1 + 'a'.code).to_character) to i;
   a2.put ((i - 1 + 'A'.code).to_character) to i;
   a3.put i to i;
 };
 1.to 3 do { i : INTEGER;
   a1.item(i).print;
   a2.item(i).print;
   a3.item(i).print;
   '\n'.print;
 };

);</lang>

Works with: UCB Logo

<lang logo>show (map [(word ?1 ?2 ?3)] [a b c] [A B C] [1 2 3])  ; [aA1 bB2 cC3]

(foreach [a b c] [A B C] [1 2 3] [print (word ?1 ?2 ?3)])  ; as above, one per line</lang>

Lua

This can be done with a simple for loop: <lang lua> a1, a2, a3 = {a , b , c } , { A , B , C } , { 1 , 2 , 3 } for i = 1, 3 do print(a1[i],a2[i],a3[i]) end </lang> but it may be more enlightening (and in line with the spirit of the challenge) to use the generic for: <lang lua> function iter(a, b, c)

 local i = 0
 return function()
   i = i + 1
   return a[i], b[i], c[i]
 end

end

for u, v, w in iter(a1, a2, a3) do print(u, v, w) end </lang>

Modula-3

<lang modula3>MODULE MultiArray EXPORTS Main;

IMPORT IO, Fmt;

TYPE ArrIdx = [1..3];

VAR

 arr1 := ARRAY ArrIdx OF CHAR {'a', 'b', 'c'};
 arr2 := ARRAY ArrIdx OF CHAR {'A', 'B', 'C'};
 arr3 := ARRAY ArrIdx OF INTEGER {1, 2, 3};

BEGIN

 FOR i := FIRST(ArrIdx) TO LAST(ArrIdx) DO
   IO.Put(Fmt.Char(arr1[i]) & Fmt.Char(arr2[i]) & Fmt.Int(arr3[i]) & "\n");
 END;

END MultiArray.</lang>

MUMPS

Pieces of String version <lang MUMPS> LOOPMULT

N A,B,C,D,%
S A="a,b,c,d"
S B="A,B,C,D"
S C="1,2,3"
S D=","
F %=1:1:$L(A,",") W !,$P(A,D,%),$P(B,D,%),$P(C,D,%)
K A,B,C,D,%
Q

</lang> When there aren't enough elements, a null string will be returned from the $Piece function.

USER>d LOOPMULT^ROSETTA
 
aA1
bB2
cC3
dD

Local arrays version <lang MUMPS> LOOPMULU

N A,B,C,D,%
S A(1)="a",A(2)="b",A(3)="c",A(4)="d"
S B(1)="A",B(2)="B",B(3)="C",B(4)="D"
S C(1)="1",C(2)="2",C(3)="3"
; will error    S %=$O(A("")) F  Q:%=""  W !,A(%),B(%),C(%) S %=$O(A(%))
S %=$O(A("")) F  Q:%=""  W !,$G(A(%)),$G(B(%)),$G(C(%)) S %=$O(A(%)) 
K A,B,C,D,%

</lang>

The commented out line will throw an <UNDEFINED> error when trying to look up D(4). Using the $Get function as a wrapper means that if the subscript for the array doesn't exist, a null string will be returned. This same syntax is used for globals (permanent variables, that have a caret "^" as the first character).

USER>D LOOPMULU^ROSETTA
 
aA1
bB2
cC3
dD
USER>D LOOPMULV^ROSETTA

aA1
bB2
cC3
dD
 S %=$O(A("")) F  Q:%=""  W !,A(%),B(%),C(%) S %=$O(A(%))
                                        ^
<UNDEFINED>LOOPMULV+5^ROSETTA *C(4)

OCaml

an immediate solution: <lang ocaml>let a1 = [| 'a'; 'b'; 'c' |] and a2 = [| 'A'; 'B'; 'C' |] and a3 = [| '1'; '2'; '3' |] ;;

Array.iteri (fun i c1 ->

 print_char c1;
 print_char a2.(i);
 print_char a3.(i);
 print_newline()

) a1 ;;</lang>

a more generic solution could be to use a function which iterates over a list of arrays:

<lang ocaml>let n_arrays_iter ~f = function

 | [] -> ()
 | x::xs as al ->
     let len = Array.length x in
     let b = List.for_all (fun a -> Array.length a = len) xs in
     if not b then invalid_arg "n_arrays_iter: arrays of different length";
     for i = 0 to pred len do
       let ai = List.map (fun a -> a.(i)) al in
       f ai
     done</lang>

this function raises Invalid_argument exception if arrays have different length, and has this signature:

<lang ocaml>val n_arrays_iter : f:('a list -> unit) -> 'a array list -> unit</lang>

how to use it with arrays a1, a2 and a3 defined before:

<lang ocaml>let () =

 n_arrays_iter [a1; a2; a3] ~f:(fun l ->
   List.iter print_char l;
   print_newline());
</lang>

Oz

<lang oz>for

  I in [a b c]
  J in ['A' 'B' 'C']
  K in [1 2 3]

do

  {System.showInfo I#J#K}

end</lang>

The loop will stop when the shortest list is exhausted.

Perl

<lang perl>sub zip (&@) {

       my $code = shift;
       my $min;
       $min = $min && $#$_ > $min ? $min : $#$_ for @_;
       for my $i(0..$min){ $code->(map $_->[$i] ,@_) }

} my @a1 = qw( a b c ); my @a2 = qw( A B C ); my @a3 = qw( 1 2 3 );

zip { print @_,"\n" }\(@a1, @a2, @a3);</lang>

This implementation will stop producing items when the shortest array ends.

Perl 6

Works with: Rakudo version #21 "Seattle"

<lang perl6>for <a b c> Z <A B C> Z (1, 2, 3) -> $x, $y, $z {

  say $x, $y, $z;

}</lang>

The Z operator stops emitting items as soon as the shortest input list is exhausted.

PHP

<lang PHP>$a = array('a', 'b', 'c'); $b = array('A', 'B', 'C'); $c = array('1', '2', '3'); //These don't *have* to be strings, but it saves PHP from casting them later

if ((sizeOf($a) !== sizeOf($b)) || (sizeOf($b) !== sizeOf($c))){

 throw new Exception('All three arrays must be the same length');

} foreach ($a as $key => $value){

 echo "{$a[$key]}{$b[$key]}{$c[$key]}\n";

}</lang>

This implementation throws an exception if the arrays are not all the same length.

PicoLisp

<lang PicoLisp>(mapc prinl

  '(a b c)
  '(A B C)
  (1 2 3) )</lang>

The length of the first argument list controls the operation. If subsequent lists are longer, their remaining values are ignored. If they are shorter, NIL is passed to the function.

PL/I

<lang PL/I> declare P(3) character (1) initial ('a', b', 'c'),

       Q(3) character (1) initial ('A', 'B', 'C'),
       R(3) fixed decimal (1) initial (1, 2, 3);

do i = lbound(P,1) to hbound(P,1);

  put skip edit (P(i), Q(i), R(i)) (2 A, F(1));

end; </lang>

PowerBASIC

<lang powerbasic>FUNCTION PBMAIN () AS LONG

   DIM x(2), y(2) AS STRING * 1
   DIM z(2) AS LONG
   'data
   ARRAY ASSIGN x() = ("a", "b", "c")
   ARRAY ASSIGN y() = ("A", "B", "C")
   ARRAY ASSIGN z() = (1, 2, 3)
   'set upper bound
   C& = UBOUND(x)
   IF UBOUND(y) > C& THEN C& = UBOUND(y)
   IF UBOUND(z) > C& THEN C& = UBOUND(z)
   OPEN "output.txt" FOR OUTPUT AS 1
   FOR L& = 0 TO C&
       IF L& <= UBOUND(x) THEN PRINT #1, x(L&);
       IF L& <= UBOUND(y) THEN PRINT #1, y(L&);
       IF L& <= UBOUND(z) THEN PRINT #1, TRIM$(STR$(z(L&)));
       PRINT #1,
   NEXT
   CLOSE

END FUNCTION</lang>

PureBasic

<lang PureBasic>OpenConsole()

Fill arrays

Dim a.s(2) Dim b.s(2) Dim c(2) For Arrayposition = 0 To ArraySize(a())

 a(Arrayposition) = Chr(Asc("a") + Arrayposition)
 b(Arrayposition) = Chr(Asc("A") + Arrayposition)
 c(Arrayposition) = Arrayposition + 1

Next

loop over them

For Arrayposition = 0 To ArraySize(a())

 PrintN(a(Arrayposition) + b(Arrayposition) + Str(c(Arrayposition)))

Next Input() ;wait for Enter before ending</lang>

If they have different lengths there are two cases:
a() is the shortest one: Only elements up to maximum index of a() are printed
a() is bigger than another one: if exceeding index to much, program crashes,
else it may work because there is some "free space" after end of assigned array memory.
For example if a has size 4, line dD4 will also be printed. size 20 leads to an crash
This is because ReDim becomes slow if everytime there is a change to array size new memory has to be allocated.

Python

Using zip(): <lang python>>>> print ( '\n'.join(.join(x) for x in zip('abc', 'ABC', '123')) ) aA1 bB2 cC3 >>></lang> If lists are different lengths, zip() stops after the shortest one.

Using map(): <lang python>>>> print ( '\n'.join(map(lambda *x: .join(x), 'abc', 'ABC', '123')) ) aA1 bB2 cC3 >>></lang> If lists are different lengths, map() in Python 2.x pretends that the shorter lists were extended with None items; map() in Python 3.x stops after the shortest one.

Using itertools.imap() (Python 2.x): <lang python>from itertools import imap

def join3(a,b,c):

  print a+b+c

imap(join3,'abc','ABC','123')</lang> If lists are differnt lengths, imap() stops after the shortest is exhausted.

zip_longest

Python 3.X has zip_longest which fills shorter iterables with its fillvalue argument which defaults to None (similar to the behavior of map() in Python 2.x): <lang python>>>> from itertools import zip_longest >>> print ( '\n'.join(.join(x) for x in zip_longest('abc', 'ABCD', '12345', fillvalue='#')) ) aA1 bB2 cC3

  1. D4
    1. 5

>>></lang> (The Python 2.X equivalent is itertools.izip_longest)

R

<lang R>multiloop <- function(...) {

  # Retrieve inputs and convert to a list of character strings
  arguments <- lapply(list(...), as.character)
  
  # Get length of each input
  lengths <- sapply(arguments, length)
  # Loop over elements
  for(i in seq_len(max(lengths)))
  {
     # Loop over inputs
     for(j in seq_len(nargs()))
     {
        # print a value or a space (if that input has finished)
        cat(ifelse(i <= lengths[j], argumentsj[i], " "))
     }
     cat("\n")
  }

} multiloop(letters[1:3], LETTERS[1:3], 1:3)</lang>

Ruby

<lang ruby>['a','b','c'].zip(['A','B','C'], [1,2,3]).each {|i,j,k| puts "#{i}#{j}#{k}"}</lang> or <lang ruby>['a','b','c'].zip(['A','B','C'], [1,2,3]).each {|a| puts a.join()}</lang> Array#zip iterates once for each element of the receiver. If an argument array is longer, the excess elements are ignored. If an argument array is shorter, the value nil is supplied.

SuperCollider

<lang SuperCollider> ([\a,\b,\c]+++[\A,\B,\C]+++[1,2,3]).do({|array| array.do(_.post); "".postln }) </lang>

Ada

<lang Ada>with Ada.Text_IO; use Ada.Text_IO;

procedure Array_Loop_Test is

  type Array_Index is range 1..3;
  A1 : array (Array_Index) of Character := "abc";
  A2 : array (Array_Index) of Character := "ABC";
  A3 : array (Array_Index) of Integer   := (1, 2, 3);

begin

  for Index in Array_Index'Range loop
     Put_Line (A1 (Index) & A2 (Index) & Integer'Image (A3 (Index))(2));
  end loop;

end Array_Loop_Test;</lang>

Tcl

<lang tcl>set list1 {a b c} set list2 {A B C} set list3 {1 2 3} foreach i $list1 j $list2 k $list3 {

   puts "$i$j$k"

}</lang> If lists are different lengths, the manual [1] says: "The total number of loop iterations is large enough to use up all the values from all the value lists. If a value list does not contain enough elements for each of its loop variables in each iteration, empty values are used for the missing elements."

Ursala

Compute the transpose of the list formed of the three lists. If they're of unequal lengths, an exception occurs. <lang Ursala>#show+

main = ~&K7 <'abc','ABC','123'></lang> output:

aA1
bB2
cC3